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)
但我无法弄清楚如何正确对待“:”当它出现的字符串中。有人能帮我吗?
在此先感谢!
编辑:顺便说一下,有没有更紧凑的方式来解析这样的字符串,也许使用正则表达式?
答
编辑:顺便说一下,在那里,也许 使用正则表达式解析这种串的更紧凑的方式?
也许更清洁(略更有效)的方式:
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)
我会忍不住用正则表达式解析它 - 我不是专家,但是这将是我会做的方式 - 因为“语法”似乎是有规律的。 –
@xnx我的想法正确 –
为什么6有一个冒号? –