Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中将数字字符串范围转换为列表_Python_List_String - Fatal编程技术网

如何在Python中将数字字符串范围转换为列表

如何在Python中将数字字符串范围转换为列表,python,list,string,Python,List,String,我希望能够将字符串(如“1,2,5-7,10”)转换为python列表(如[1,2,5,6,7,10])。我环顾四周,发现了这个问题,但我想知道在Python中是否有一种干净而简单的方法可以做到这一点。这可能有些过分,但我喜欢pyparsing: def f(x): result = [] for part in x.split(','): if '-' in part: a, b = part.split('-')

我希望能够将字符串(如“1,2,5-7,10”)转换为python列表(如[1,2,5,6,7,10])。我环顾四周,发现了这个问题,但我想知道在Python中是否有一种干净而简单的方法可以做到这一点。

这可能有些过分,但我喜欢pyparsing:

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]
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')
从pyparsing导入*
def回流范围(strg、loc、toks):
如果len(toks)==1:
返回整数(toks[0])
其他:
返回范围(int(toks[0]),int(toks[1])+1)
def解析字符串:
expr=Forward()
term=(Word(nums)+可选(Literal('-')。suppress()+Word(nums)))。setParseAction(返回范围)

expr我能够对这个问题做出正确的理解:

>>> 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]
另一个假装理解的答案只是一个for循环,因为最终的列表被丢弃了。:)


对于Python2,您甚至可以删除对
列表的调用

啊,答案太冗长了!下面是一个简短而优雅的答案:

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(',')])
演示:


易于修改以处理负数或返回列表。还需要从itertools导入链中获取
,但如果您不使用
范围
对象(或
sum(map(list,iter),[])
),并且您不在乎懒惰,您可以用
sum(…,[])
替换它。

没有理解能力打败我

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))), [])
<>最好的部分是在理解过程中使用变量<代码> i <代码>两次。

>>> convert('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]
非常短,优雅(imho):

从这里开始:


这将是一个很好的生成器。通过将else替换为
elif part!='',可以实现在前导或尾随逗号上不爆炸
>>> convert('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]
>>> 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]
def number(a, just_try=False):
    """
    Parse any representation of number from string.
    """
    try:
        # First, we try to convert to integer.
        # (Note, that all integer can be interpreted as float and hex number.)
        return int(a)
    except:
        # The order of the following convertions doesn't matter.
        # The integer convertion has failed because `a` contains hex digits [x,a-f] or a decimal
        # point ['.'], but not both.
        try:
            return int(a, 16)
        except:
            try:
                return float(a)
            except:
                if just_try:
                    return a
                else:
                    raise


def str2numlist(s):
    """
    Convert a string parameter to iterable object.
    """
    return [y for x in s.split(',') for y in str_ranges_to_list(x) ]


def str_ranges_to_list(s):
    """
    Convert a string parameter to iterable object.
    """
    s = s.strip()
    try:
        begin,end=s.split(':')
        return range(number(begin), number(end))
    except ValueError: # not enough values to unpack
        return [number(s)]