0

I'm trying to get a list from the range of numbers in a string. How I can do that in Python 3?

I want to convert the following string:

s = "1-4, 6, 7-10"

into this list:

l = [1, 2, 3, 4, 6, 7, 8, 9, 10]
MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46

4 Answers4

2

You could first split on ',' characters. If you find a single value, just convert to int. If you find a dash, convert to a range of integers.

def listify(s):
    output = []
    for i in s.split(','):
        if '-' in i:
            start, stop = [int(j) for j in i.split('-')]
            output += list(range(start, stop+1))
        else:
            output.append(int(i))
    return output

>>> listify("1-4, 6, 7-10")
[1, 2, 3, 4, 6, 7, 8, 9, 10]
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 1
    Any reason you've used `output +=` instead of `output.extend`? – aneroid May 27 '20 at 15:56
  • You should do s.split(', '), not s.split(','). – Red May 27 '20 at 15:57
  • 1
    @AnnZen That's more accurate but it's not needed because the result of `split(',')` (without the space) is being passed to `int()` (eventually) and `int()` will handle multiple extra spaces on either side: `int(' 6') == int('6 ') == int(' 6 ') == 6` is `True`. _(the last one is 3 spaces, the number 6, and then 4 spaces, but it doesn't render correctly.)_ – aneroid May 27 '20 at 16:02
  • 2
    @aneroid regarding `+=` vs `extend` I just prefer the former for terseness, though [they're essentially equivalent](https://stackoverflow.com/questions/3653298/concatenating-two-lists-difference-between-and-extend) in most cases – Cory Kramer May 27 '20 at 20:30
0

You have a list which can either have an int or a range,
you can iterate and handle them separately

In [8]: series = []

In [9]: for token in "1-4, 6, 7-10".split(","):
   ...:     token = token.strip()
   ...:     if token.isnumeric():
   ...:         series.append(int(token))
   ...:     else:
   ...:         s, e = tuple(map(int, token.split("-")))
   ...:         # splits "4-6" and converts to int
   ...:         series.extend(list(range(s, e+1)))
   ...:

In [10]: series
Out[10]: [1, 2, 3, 4, 6, 7, 8, 9, 10]
mojozinc
  • 164
  • 8
0

Like this:

s = "3-12, 7, 1, 3-6"
d = []
for l in s.split(', '):
    if '-' in l:
        q = l.split('-')
        for n in range(int(q[0]),int(q[1])+1):
            d.append(n)
    else:
        d.append(int(l))
print(d)

Output:

[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 7, 1, 3, 4, 5, 6]
Red
  • 26,798
  • 7
  • 36
  • 58
0

If you happen to be really motivated to do this as compactly as possible, it can be done as a nested comprehension:

>>> [i
...     for r in (list(map(int, q.split("-")))
...         for q in s.split(", ")
...     ) for i in range(r[0], r[-1]+1)
... ]
[1, 2, 3, 4, 6, 7, 8, 9, 10]

Here it is built up step by step:

>>> s.split(", ")
['1-4', '6', '7-10']
>>> [q.split("-") for q in s.split(", ")]
[['1', '4'], ['6'], ['7', '10']]
>>> [list(map(int, q.split("-")))
...     for q in s.split(", ")
... ]
[[1, 4], [6], [7, 10]]
>>>
>>> [range(r[0], r[-1]+1)
...     for r in (list(map(int, q.split("-")))
...     for q in s.split(", "))
... ]
[range(1, 5), range(6, 7), range(7, 11)]
>>>
>>> [i
...     for r in (list(map(int, q.split("-")))
...         for q in s.split(", ")
...     ) for i in range(r[0], r[-1]+1)
... ]
[1, 2, 3, 4, 6, 7, 8, 9, 10]
Samwise
  • 68,105
  • 3
  • 30
  • 44