python中有没有什么东西可以将递增的整数列表转换为范围列表?
例如,给定集合{0,1,2,3,4,7,8,9,11},我想得到{ {0,4 },{7,9},{11,11} }。
我可以写一个程序来做这件事,但是我想知道python中是否有一个内置的函数。
发布于 2011-01-08 03:04:50
使用itertools.groupby()
会产生一个简明但棘手的实现:
import itertools
def ranges(i):
for a, b in itertools.groupby(enumerate(i), lambda pair: pair[1] - pair[0]):
b = list(b)
yield b[0][1], b[-1][1]
print(list(ranges([0, 1, 2, 3, 4, 7, 8, 9, 11])))
输出:
[(0, 4), (7, 9), (11, 11)]
发布于 2015-01-30 04:43:42
生成范围对:
def ranges(lst):
s = e = None
r = []
for i in sorted(lst):
if s is None:
s = e = i
elif i == e or i == e + 1:
e = i
else:
r.append((s, e))
s = e = i
if s is not None:
r.append((s, e))
return r
示例:
>>> lst = [1, 5, 6, 7, 12, 15, 16, 17, 18, 30]
>>> print repr(ranges(lst))
[(1, 1), (5, 7), (12, 12), (15, 18), (30, 30)]
作为一个生成器:
def gen_ranges(lst):
s = e = None
for i in sorted(lst):
if s is None:
s = e = i
elif i == e or i == e + 1:
e = i
else:
yield (s, e)
s = e = i
if s is not None:
yield (s, e)
示例:
>>> lst = [1, 5, 6, 7, 12, 15, 16, 17, 18, 30]
>>> print repr(','.join(['%d' % s if s == e else '%d-%d' % (s, e) for (s, e) in gen_ranges(lst)]))
'1,5-7,12,15-18,30'
发布于 2019-11-06 20:16:14
由于已经有两年左右没有新的答案了,这里有一个适合僵尸爱好者的答案!
如果不想使用itertools或生成器,下面的代码使用逻辑(!)。它使用一个集合(参见问题!)用于输入,并返回一个适当范围的列表作为结果;不过,根据需要调整代码非常容易。
def ranges(l_set: set) ->list:
rb_set = sorted(l_set - {i +1 for i in l_set})
re_set = sorted(l_set - {i -1 for i in l_set})
return [range(rb_set[i], re_set[i]+1) for i in range(len(rb_set))]
例如:
>>>ranges({6, 9, 10, 7, 8, 2, 3, 14})
[range(2, 4), range(6, 11), range(14, 15)]
>>>ranges({6, 7, 3, 15, 8, 5, 12, 0, 12, 7, 15, 6, 14, 8, 16})
[range(0, 1), range(3, 4), range(5, 9), range(12, 13), range(14, 17)]
https://stackoverflow.com/questions/4628333
复制相似问题