Python - 从字符串创建集合

问题描述:

我有格式为"1-3 6:10-11 7-9"的字符串,并从它们中创建数字集合,如下所示{1,2,3,6,10,11,7,8,9}Python - 从字符串创建集合

有关创建从号码的范围内设定,我有以下代码:

def create_set(src): 
    lset = [] 
    if len(src) > 0: 
     pos = src.find('-') 
     if pos != -1: 
      first = int(src[:pos]) 
      last = int(src[pos+1:]) 
     else: 
      return [int(src)] # Only one number 
     for j in range (first, last+1): 
      lset.append(j) 
     return set(lset) 

但我无法弄清楚如何正确对待“:”当它出现的字符串中。有人能帮我吗?

在此先感谢!

编辑:顺便说一下,有没有更紧凑的方式来解析这样的字符串,也许使用正则表达式?

+0

我会忍不住用正则表达式解析它 - 我不是专家,但是这将是我会做的方式 - 因为“语法”似乎是有规律的。 –

+0

@xnx我的想法正确 –

+1

为什么6有一个冒号? –

编辑:顺便说一下,在那里,也许 使用正则表达式解析这种串的更紧凑的方式?

也许更清洁(略更有效)的方式:

import re 
import itertools 

allGroups = re.findall(r"(\d+)(?:-(\d+)|:)", s) 
expanded = [range(int(x), (int(x) if y == '' else int(y)) + 1) for x, y in allGroups] 
print {x for x in itertools.chain.from_iterable(expanded)} 

说明:

匹配的所有字符串,如 'AB' 或 '答:' 并返回一个列表(一, b)和(分别是, '')对:

allGroups = re.findall(r"(\d+)(?:-(\d+)|:)", s) 

这产生:

[('1', '3'), ('6', ''), ('10', '11'), ('7', '9')] 

使用列表理解将(x,y)的所有对扩展到范围(x,y + 1)中的所有数字列表中,注意将(x,'')情况作为(x, X + 1):

expanded = [range(int(x), (int(x) if y == '' else int(y)) + 1) for x, y in allGroups] 

这产生:

[[1, 2, 3], [6], [10, 11], [7, 8, 9]] 

使用itertools.chain.from_iterable()到列表清单变换成一个单一的迭代,其由一组理解迭代到最终组:

print {x for x in itertools.chain.from_iterable(expanded)} 

这将产生:

set([1, 2, 3, 6, 7, 8, 9, 10, 11]) 
+0

谢谢,FujiApple,这个解决方案还具有返回排序列表的好处。 – maurobio

像这样的事情可能会为你工作:

s = '1-3 6:10-11 7-9' 
s = s.replace(':', ' ') 
lset = set() 
fs = s.split() 
for f in fs: 
    r = f.split('-') 
    if len(r)==1: 
     # add a single number 
     lset.add(int(r[0])) 
    else: 
     # add a range of numbers (inclusive of the endpoints) 
     lset |= set(range(int(r[0]), int(r[1])+1)) 
print(lset) 
+0

谢谢,xnx!它非常完美! – maurobio

+0

这个答案很好,但可以选择下面的替代方案,也许更简单。 – FujiApple