I had the same issue and there is a perfect solution to it -zfill method

An example of usage:

>>> str('1').zfill(7)
'0000001'

What you need to do is to create a generator for N numbers and fill its string representation with zeros.

>>> for i in range(1, 18):
...     str(i).zfill(2)
...
'01'
'02'
'03'
...
'16'
'17'
Answer from taras on Stack Overflow
🌐
Stanford CS
cs.stanford.edu › people › nick › py › python-range.html
Python range() Function
The most common form is range(n), given integer n returns a numeric series starting with 0 and extending up to but not including n, e.g. range(6) returns 0, 1, 2, 3, 4, 5. With Python's zero-based indexing, the contents of a string length 6, are at index numbers 0..5, so range(6) will produce exactly the index numbers for a string length 6, like this:
Discussions

Convert range(r) to list of strings of length 2 in python - Stack Overflow
I just want to change a list (that I make using range(r)) to a list of strings, but if the length of the string is 1, tack a 0 on the front. I know how to turn the list into strings using ranger=... More on stackoverflow.com
🌐 stackoverflow.com
python - Convert List of Numbers to String Ranges - Stack Overflow
I'd like to know if there is a simple (or already created) way of doing the opposite of this: Generate List of Numbers from Hyphenated.... This link could be used to do: >> list(hyphen_ran... More on stackoverflow.com
🌐 stackoverflow.com
Printing string range in Python - Stack Overflow
Why it does not increment when ... wanted to understand the behavior in detail. ... The first output if first char of each of second output. That's uncleat what you don't understand ... s[i:i+2] select two characters of s each time, and for the last loop, it selects (2:4), which exceeds the length of the string... More on stackoverflow.com
🌐 stackoverflow.com
python range and string - Stack Overflow
It takes a function and a list, and applies the function to each item in the list. ' '.join is a peculiarity of Python. What it does is take a list and turn it into a string by putting a space between each of the items. You would think that it'd be a function you call on the list, but in Python it's a function on the string instead. ... numbers = range... More on stackoverflow.com
🌐 stackoverflow.com
July 28, 2015
🌐
YouTube
youtube.com › watch
python range to string list - YouTube
Download this code from https://codegive.com In Python, the range function is commonly used to generate a sequence of numbers. While range itself returns a r...
Published   February 2, 2024
🌐
EyeHunts
tutorial.eyehunts.com › home › python range to the list of strings | example code
Python range to the list of strings | Example code - EyeHunts
August 27, 2021 - Python simple example code. There is a perfect solution to it -zfill method. Generator for N numbers and fill its string representation with zeros. list1 = [] for i in range(1, 7): list1.append(str(i).zfill(2)) print(list1) Output: lst = range(11) ...
Top answer
1 of 5
6

One approach could be "eating" piece by piece the input sequence and store the partial range results untill you've got them all:

def formatter(start, end, step):
    return '{}-{}:{}'.format(start, end, step)
    # return '{}-{}:{}'.format(start, end + step, step)

def helper(lst):
    if len(lst) == 1:
        return str(lst[0]), []
    if len(lst) == 2:
        return ','.join(map(str,lst)), []

    step = lst[1] - lst[0]
    for i,x,y in zip(itertools.count(1), lst[1:], lst[2:]):
        if y-x != step:
            if i > 1:
                return formatter(lst[0], lst[i], step), lst[i+1:]
            else:
                return str(lst[0]), lst[1:]
    return formatter(lst[0], lst[-1], step), []

def re_range(lst):
    result = []
    while lst:
        partial,lst = helper(lst)
        result.append(partial)
    return ','.join(result)

I test it with a bunch of unit tests and it passed them all, it can handle negative numbers too, but they'll look kind of ugly (it's really anybody's fault).

Example:

>>> re_range([1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28])
'1,4-6:1,10,15-18:1,22,25-28:1'
>>> re_range([1, 3, 5, 7, 8, 9, 10, 11, 13, 15, 17])
'1-7:2,8-11:1,13-17:2'

Note: I wrote the code for Python 3.


Performance

I didn't put any performance effort in the solution above. In particular, every time a list get re-builded with slicing, it might take some time if the input list has a particular shape. So, the first simple improvement would be using itertools.islice() where possible.

Anyway here's another implementation of the same algorithm, that scan through the input list with a scan index instead of slicing:

def re_range(lst):
    n = len(lst)
    result = []
    scan = 0
    while n - scan > 2:
        step = lst[scan + 1] - lst[scan]
        if lst[scan + 2] - lst[scan + 1] != step:
            result.append(str(lst[scan]))
            scan += 1
            continue

        for j in range(scan+2, n-1):
            if lst[j+1] - lst[j] != step:
                result.append(formatter(lst[scan], lst[j], step))
                scan = j+1
                break
        else:
            result.append(formatter(lst[scan], lst[-1], step))
            return ','.join(result)

    if n - scan == 1:
        result.append(str(lst[scan]))
    elif n - scan == 2:
        result.append(','.join(map(str, lst[scan:])))

    return ','.join(result)

I stopped working on it once it got ~65% faster than the previous top solution, it seemed enough :)

Anyway I'd say that there might still be room for improvement (expecially in the middle for-loop).

2 of 5
2

This is a comparison of the 3 methods. Change the amount of data and the density via the values below...no matter what values I use, the first solution seems to be the quickest for me. For very large sets of data, the third solution becomes very slow.

EDITED

Edited to include comments below and add in a new solution. The last solution seems to be the quickest now.

import numpy as np
import itertools
import random
import timeit

# --- My Solution --------------------------------------------------------------
def list_to_ranges1(data):
   data = sorted(data)
   diff_data = np.diff(data)
   ranges = []
   i = 0
   skip_next = False
   for k, iterable in itertools.groupby(diff_data, None):
      rng = list(iterable)
      step = rng[0]
      if skip_next:
         skip_next = False
         rng.pop()

      if len(rng) == 0:
         continue
      elif len(rng) == 1:
         ranges.append('%d' % data[i])
      elif step == 1:
         ranges.append('%d-%d' % (data[i], data[i+len(rng)]+step))
         i += 1
         skip_next = True
      else:
         ranges.append('%d-%d:%d' % (data[i], data[i+len(rng)]+step, step))
         i += 1
         skip_next = True
      i += len(rng)

   if len(rng) == 0 or len(rng) == 1:
      ranges.append('%d' % data[i])
   return ','.join(ranges)

# --- Kaidence Solution --------------------------------------------------------
# With a minor edit for use in range function
def list_to_ranges2(data):
   onediff = np.diff(data)
   twodiff = np.diff(onediff)
   increments, breakingindices = [], []
   for i in range(len(twodiff)):
       if twodiff[i] != 0:
           breakingindices.append(i+2)  # Correct index because of the two diffs
           increments.append(onediff[i]) # Record the increment for this section

  # Increments and breakingindices should be the same size
   str_list = []
   start = data[0]
   for i in range(len(breakingindices)):
       str_list.append("%d-%d:%d" % (start,
                                     data[breakingindices[i]-1] + increments[i],
                                     increments[i]))
       start = data[breakingindices[i]]
   str_list.append("%d-%d:%d" % (start,
                                 data[len(data)-1] + onediff[len(onediff)-1],
                                 onediff[len(onediff)-1]))
   return ','.join(str_list)

# --- Rik Poggi Solution -------------------------------------------------------
# With a minor edit for use in range function
def helper(lst):
    if len(lst) == 1:
        return str(lst[0]), []
    if len(lst) == 2:
        return ','.join(map(str,lst)), []

    step = lst[1] - lst[0]
    #for i,x,y in itertools.izip(itertools.count(1), lst[1:], lst[2:]):
    for i,x,y in itertools.izip(itertools.count(1),
                                itertools.islice(lst, 1, None, 1),
                                itertools.islice(lst, 2, None, 1)):
        if y-x != step:
            if i > 1:
                return '{}-{}:{}'.format(lst[0], lst[i]+step, step), lst[i+1:]
            else:
                return str(lst[0]), lst[1:]
    return '{}-{}:{}'.format(lst[0], lst[-1]+step, step), []

def list_to_ranges3(lst):
    result = []
    while lst:
        partial,lst = helper(lst)
        result.append(partial)
    return ','.join(result)

# --- Rik Poggi Solution 2 -----------------------------------------------------
def formatter(start, end, step):
    #return '{}-{}:{}'.format(start, end, step)
    return '{}-{}:{}'.format(start, end + step, step)

def list_to_ranges4(lst):
    n = len(lst)
    result = []
    scan = 0
    while n - scan > 2:
        step = lst[scan + 1] - lst[scan]
        if lst[scan + 2] - lst[scan + 1] != step:
            result.append(str(lst[scan]))
            scan += 1
            continue

        for j in xrange(scan+2, n-1):
            if lst[j+1] - lst[j] != step:
                result.append(formatter(lst[scan], lst[j], step))
                scan = j+1
                break
        else:
            result.append(formatter(lst[scan], lst[-1], step))
            return ','.join(result)

    if n - scan == 1:
        result.append(str(lst[scan]))
    elif n - scan == 2:
        result.append(','.join(itertools.imap(str, lst[scan:])))

    return ','.join(result)

# --- Test Function ------------------------------------------------------------
def test_data(data, f_to_test):
   data_str = f_to_test(data)
   _list = []
   for r in data_str.replace('-',':').split(','):
      r = [int(a) for a in r.split(':')]
      if len(r) == 1:
         _list.extend(r)
      elif len(r) == 2:
         _list.extend(range(r[0], r[1]))
      else:
         _list.extend(range(r[0], r[1], r[2]))
   return _list

# --- Timing Tests -------------------------------------------------------------
# Generate some sample data...
data_list = []
for i in range(5):
   # Note: using the "4000" and "5000" values below, the relative density of
   # the data can be changed.  This has a huge effect on the results
   # (particularly on the results for list_to_ranges3 which uses recursion).
   data_list.append(sorted(list(set([random.randint(1,4000) for a in \
                                      range(random.randint(5,5000))]))))

testfuncs = list_to_ranges1, list_to_ranges2, list_to_ranges3, list_to_ranges4
for f in testfuncs:
   print '\n', f.__name__
   for i, data in enumerate(data_list):
      t = timeit.Timer('f(data)', 'from __main__ import data, f')
      #print f(data)
      print i, data==test_data(data, f), round(t.timeit(200), 3)
Find elsewhere
🌐
AskPython
askpython.com › python › string › string-alphabet-range-python
String - Alphabet Range in Python - AskPython
May 30, 2023 - In this article, we’re going to explore strings in Python and, more specifically, the string module of Python and learn to get a range of alphabets as a string and manipulate strings using different functionalities available in Python.
🌐
W3Schools
w3schools.com › python › ref_func_range.asp
Python range() Function
Remove List Duplicates Reverse ... Training ... The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number. ... If you want ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-extract-range-characters-from-string
Python - Extract range characters from String - GeeksforGeeks
June 2, 2023 - In this, we check for character in range using comparison operation and list comprehension does task of iteration and creation of new list. Then join() can be employed to reconvert to string.
🌐
Python documentation
docs.python.org › 3 › library › stdtypes.html
Built-in Types — Python 3.14.6 documentation
The linspace recipe shows how to implement a lazy version of range suitable for floating-point applications. The following table summarizes the text and binary sequence types methods by category. Textual data in Python is handled with str objects, or strings.
🌐
GeeksforGeeks
geeksforgeeks.org › python › alphabet-range-in-python
Alphabet range in Python - GeeksforGeeks
July 23, 2025 - Using these functions, you can generate any range of characters by specifying their ASCII values. List comprehensions provide a concise way to create lists. You can use them to generate a list of characters and then join them into a string if needed.
🌐
Dot Net Perls
dotnetperls.com › for-python
Python - for: Loop Over String Characters - Dot Net Perls
January 4, 2025 - Here is a program that loops over a string. The value "abc" has 3 letters in it—3 characters. We use the for-keyword. Tip If you need to get adjacent characters, or test many indexes at once, the for-loop that uses range() is best.
🌐
Reddit
reddit.com › r/learnpython › not really understanding when to use for i in string vs for i in range(len(string))
r/learnpython on Reddit: Not really understanding when to use for I in string vs for I in range(len(string))
September 27, 2020 -

Just looking for clarification for this very simple thing. Please correct me if I’m wrong but from what I understand, in for i in string, it takes each element in the string over the entire length. For i in range(len(string)) it indexes the elements and looks at the elements at each index so at position 0, string =‘x’ and at 1 string= ‘d’ ect.

If this is correct, I’m afraid I still don’t see the difference by way of when to use each or what purpose they serve.

🌐
Quora
quora.com › How-do-you-access-a-range-of-characters-from-a-string-in-Python
How to access a range of characters from a string in Python - Quora
Answer (1 of 3): Python – Extract range characters from String Given a String, extract characters only which lie between given letters. > Input : test_str = ‘geekforgeeks is best’, strt, end = “g”, “s” Output : gkorgksiss Explanation : All characters after g and before s are retained.
🌐
Stanford
web.stanford.edu › class › archive › cs › cs106a › cs106a.1204 › handouts › py-range.html
Python range() Function
The most common form is range(n), for integer n, which returns a numeric series starting with 0 and extending up to but not including n, e.g. range(5) returns 0, 1, 2, 3, 4. This is perfect for generating the index numbers into, for example, a string.. >>> s = 'Python' >>> len(s) 6 >>> for ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-construct-n-range-equilength-string-list
Python | Construct N Range Equilength String list - GeeksforGeeks
May 17, 2023 - Number of elements required : 6 K Length range strings list : ['000', '001', '002', '003', '004', '005'] Time Complexity: O(n), where n is the length of the list test_list Auxiliary Space: O(n) additional space of size n is created where n is the number of elements in the res list · Method #3: Using List Comprehension + format method ... # Python3 code to demonstrate working of # Construct N Range Equilength String list # using format method # initialize N N = 6 # printing N print("Number of elements required : " + str(N)) # initialize K K = 3 res = ['{:0{}}'.format(i, K) for i in range(N)] # printing result print("K Length range strings list : " + str(res)) #this code is contributed by edula vinay kumar reddy