我有一个整数列表,我想在这个列表中找到长度为n的所有连续子序列。例如:
>>> int_list = [1,4,6,7,8,9]
>>> conseq_sequences(int_list, length=3)
[[6,7,8], [7,8,9]]
我能想到的最好的办法是:
def conseq_sequences(self, li, length):
return [li[n:n+length]
for n in xrange(len(li)-length+1)
if li[n:n+length] == range(li[n], li[n]+length)]
这不太可读有什么易读的蟒蛇式的方法吗?
最佳答案
下面是一个更通用的解决方案,适用于任意输入的iterable(不仅仅是序列):
from itertools import groupby, islice, tee
from operator import itemgetter
def consecutive_subseq(iterable, length):
for _, consec_run in groupby(enumerate(iterable), lambda x: x[0] - x[1]):
k_wise = tee(map(itemgetter(1), consec_run), length)
for n, it in enumerate(k_wise):
next(islice(it, n, n), None) # consume n items from it
yield from zip(*k_wise)
itertools.groupby
在输入中查找连续的子字符串,如6, 7, 8, 9
它基于the example from the docs that shows how to find runs of consecutive numbers:解决方案的关键是使用
枚举(),使连续整数都出现在同一组中
(运行)。
itertools.tee
+zip
允许在子串k-wise上迭代——是pairwise
recipe from the itertools
docs的一个泛化。next(islice(iterator, n, n), None)
来自the consume
recipe there。例子:
print(*consecutive_subseq([1,4,6,7,8,9], 3))
# -> (6, 7, 8) (7, 8, 9)
这段代码使用了Python 3语法,如果需要的话,可以根据Python 2进行调整。
另请参见,What is the most pythonic way to sort dates sequences?