How to convert numeric string ranges to a list in Python

后端 未结 6 1652
伪装坚强ぢ
伪装坚强ぢ 2020-12-08 07:44

I would like to be able to convert a string such as \"1,2,5-7,10\" to a python list such as [1,2,5,6,7,10]. I looked around and found this, but I was wondering if there is a

相关标签:
6条回答
  • 2020-12-08 08:13

    Ugh, the answers are so verbose! Here is a short and elegant answer:

    def rangeString(commaString):
        def hyphenRange(hyphenString):
            x = [int(x) for x in hyphenString.split('-')]
            return range(x[0], x[-1]+1)
        return chain(*[hyphenRange(r) for r in commaString.split(',')])
    

    Demo:

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

    Easily modifiable to handle negative numbers or return a list. Also will need from itertools import chain, but you can substitute sum(...,[]) for it if you are not working with range objects (or sum(map(list,iters),[])) and you don't care about being lazy.

    0 讨论(0)
  • 2020-12-08 08:21

    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')
    
    0 讨论(0)
  • 2020-12-08 08:21

    No comprehension beats mine!

    import re
    def convert(x):
        return sum((i if len(i) == 1 else list(range(i[0], i[1]+1))
                   for i in ([int(j) for j in i if j] for i in
                   re.findall('(\d+),?(?:-(\d+))?', x))), [])
    

    The best part is that I use variable i twice in the middle of the comprehension.

    >>> convert('1,2,5-7,10')
    [1, 2, 5, 6, 7, 10]
    
    0 讨论(0)
  • 2020-12-08 08:24

    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!

    0 讨论(0)
  • 2020-12-08 08:32

    Very short, and elegant (imho):

    >>> txt = "1,2,5-7,10"
    >>> # construct list of xranges
    >>> xranges = [(lambda l: xrange(l[0], l[-1]+1))(map(int, r.split('-'))) for r in txt.split(',')]
    >>> # flatten list of xranges
    >>> [y for x in xranges for y in x]
    [1, 2, 5, 6, 7, 10]
    
    0 讨论(0)
  • 2020-12-08 08:36
    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]
    
    0 讨论(0)
提交回复
热议问题