How to convert numeric string ranges to a list in Python

This might be an overkill, but I just like pyparsing:

from pyparsing import *

def return_range(strg, loc, toks):
    if len(toks)==1:
        return int(toks[0])
    else:
        return range(int(toks[0]), int(toks[1])+1)
def parsestring(s):
    expr = Forward()
    term = (Word(nums) + Optional(Literal('-').suppress() + Word(nums))).setParseAction(return_range)
    expr << term + Optional(Literal(',').suppress() + expr)
    return expr.parseString(s, parseAll=True)

if __name__=='__main__':
    print parsestring('1,2,5-7,10')

I was able to make a true comprehension on that question:

>>> def f(s):
    return sum(((list(range(*[int(j) + k for k,j in enumerate(i.split('-'))]))
         if '-' in i else [int(i)]) for i in s.split(',')), [])

>>> f('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]

>>> f('1,3-7,10,11-15')
[1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15]

the other answer that pretended to have a comprehension was just a for loop because the final list was discarded. :)

For python 2 you can even remove the call to list!


def f(x):
    result = []
    for part in x.split(','):
        if '-' in part:
            a, b = part.split('-')
            a, b = int(a), int(b)
            result.extend(range(a, b + 1))
        else:
            a = int(part)
            result.append(a)
    return result

>>> f('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]