6

我正在尝试向我的程序添加一个选项,该选项允许用户选择他想要执行的程序的哪些步骤。

我希望能够解析一个字符串,比如"1-3,6,8-10"和 get [1, 2, 3, 6, 8, 9, 10]

你知道 Python 中正在做的事情是否已经存在吗?

4

7 回答 7

9

此功能可以满足您的要求。它假定没有使用负数,否则需要进行一些更改来支持这种情况。

def mixrange(s):
    r = []
    for i in s.split(','):
        if '-' not in i:
            r.append(int(i))
        else:
            l,h = map(int, i.split('-'))
            r+= range(l,h+1)
    return r


print mixrange('1-3,6,8-10')
于 2013-09-12T08:57:22.697 回答
5

使用列表推导的一种方法:

s = "1-3,6,8-10"
x = [ss.split('-') for ss in s.split(',')]
x = [range(int(i[0]),int(i[1])+1) if len(i) == 2 else i for i in x]
print([int(item) for sublist in x for item in sublist])

输出:

[1, 2, 3, 6, 8, 9, 10]
于 2013-09-12T09:39:21.543 回答
3

没有内置函数,但可以使用xrange和生成器完成:

from itertools import chain

s = "1-3,6,8-10"
spans = (el.partition('-')[::2] for el in s.split(','))
ranges = (xrange(int(s), int(e) + 1 if e else int(s) + 1) for s, e in spans)
all_nums = chain.from_iterable(ranges) # loop over, or materialse using `list`
# [1, 2, 3, 6, 8, 9, 10]
于 2013-09-12T09:45:13.710 回答
1

我刚刚创建的一个小函数:

def expand(st):
    res = []
    for item in st.split(','):
        if '-' in item:
            temp = map(int, item.split('-'))
            res.extend(range(temp[0], temp[1]+1))
        else:
            res.append(int(item))
    return res

s = '1-3,6,8-10'
print expand(s)

回报:

[1, 2, 3, 6, 8, 9, 10]
于 2013-09-12T08:48:29.787 回答
1
s = '1-3,6,8-10,13-16'
temp = [x.split('-') if '-' in x else x for x in s.split(',')]
# temp = [['1', '3'], '6', ['8', '10'], ['13', '16']]
res = []
for l in temp:
    if isinstance(l, list):
        a, b = map(int, l)
        res += list(range(a, b + 1))
    else:
        res.append(int(l))

 # res = [1, 2, 3, 6, 8, 9, 10, 13, 14, 15, 16]
于 2013-09-12T09:01:50.060 回答
0
def parseIntSet(nputstr=""):
  selection = set()
  invalid = set()
  # tokens are comma seperated values
  tokens = [x.strip() for x in nputstr.split(',')]
  for i in tokens:
     try:
        # typically tokens are plain old integers
        selection.add(int(i))
     except:
        # if not, then it might be a range
        try:
           token = [int(k.strip()) for k in i.split('-')]
           if len(token) > 1:
              token.sort()
              # we have items seperated by a dash
              # try to build a valid range
              first = token[0]
              last = token[len(token)-1]
              for x in range(first, last+1):
                 selection.add(x)
        except:
           # not an int and not a range...
           invalid.add(i)
  # Report invalid tokens before returning valid selection
  print "Invalid set: " + str(invalid)
  return selection

通过:在 Python 中解析数字列表

于 2013-09-12T08:50:24.903 回答
0

啊哈,任何人的概念证明?

编辑:改进版

import itertools
s = "1-3,6,8-10"

print(list(itertools.chain.from_iterable(range(int(ranges[0]), int(ranges[1])+1) for ranges in ((el+[el[0]])[:2] for el in (miniRange.split('-') for miniRange in s.split(','))))))

现在分成几行以提高可读性:

print(list(itertools.chain.from_iterable(
    range(
        int(ranges[0]),
        int(ranges[1])+1
    )
    for ranges in 
        (
            (el+[el[0]])[:2] # Allows to get rid of the ternary condition by always adding a duplicate of the first element if it is alone
            for el in
            (miniRange.split('-') for miniRange in s.split(','))
        )
)))
于 2013-09-12T10:20:43.707 回答