[英]Splitting a list on non-sequential numbers
我有一个有序的实体列表,以不连续的顺序编号:
[1, 2, 3, 6, 7, 11, 17, 18, 19]
我想打破有差距的列表,并将结果收集到一个新列表中:
[[1, 2, 3], [6, 7], [11], [17, 18, 19]]
我觉得我想做的事情有一个名字,可能还有一个不错的图书馆 function - 但我想不出。 在我可能重新发明轮子之前,任何人都可以发光吗?
编辑:谢谢,伙计们,但我问的是这个操作和现有算法是否有名称,而不是实现 - 这就是我想出的:
def group_adjoining(elements, key=lambda x: x):
"""Returns list of lists of contiguous elements
:key: function to get key integer from list element
"""
if not elements:
return elements
result = [[elements[0]]]
for a, b in zip(elements, elements[1:]):
if key(a) + 1 == key(b):
result[-1].append(b)
else:
result.append([b])
return result
今天第一次接触到more_itertools ,我觉得这个 package 对这个问题很有用。
pip install more-itertools
from more_itertools import split_when
l = [1, 2, 3, 6, 7, 11, 17, 18, 19]
res = list(split_when(l, lambda a, b: a + 1 != b))
print(res)
普通的itertools.groupby
方法:
from itertools import groupby
lst = [1, 2, 3, 6, 7, 11, 17, 18, 19]
out = []
for _, g in groupby(enumerate(lst), lambda x: x[0] - x[1]):
out.append([v for _, v in g])
print(out)
印刷:
[[1, 2, 3], [6, 7], [11], [17, 18, 19]]
尝试贪心的方法:
lst = [1, 2, 3, 6, 7, 11, 17, 18, 19]
res = []
tmp = []
prv = lst[0]
for l in lst:
if l-prv > 1:
res.append(tmp)
tmp = []
tmp.append(l)
prv = l
res.append(tmp)
print(res)
Output: [[1, 2, 3], [6, 7], [11], [17, 18, 19]]
您可以使用一个简单的生成器。
def split(lst):
result = []
for item in lst:
if (not result) or result[-1] + 1 == item:
result.append(item)
else:
yield result
result = [item]
if result:
yield result
foo = [1, 2, 3, 6, 7, 11, 17, 18, 19]
result = [i for i in split(foo)]
print(result) # [[1, 2, 3], [6, 7], [11], [17, 18, 19]]
这假定int
的排序同构list
。
您总是可以避免使用for item in sorted(lst):
的排序假设。
使用这个简单的 function 非常简单:
li = [1, 2, 3, 6, 7, 9, 10, 11, 12, 14, 16, 17, 18]
def split(li):
result = []
temp = [li[0]]
for i in range(1, len(li)):
if li[i] - temp[-1] == 1:
temp.append(li[i])
else:
result.append(temp)
temp = [li[i]]
result.append(temp)
return result
print(split(li))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.