例如,我们有
结果必须为
如果写作有些不清楚,请谅解,英语不是我的母语。
[0, 1, 3, 5, 7, 8, 9, 10, 12, 13]
。结果必须为
7, 8, 9, 10
,因为它们是相邻的,索引智能和连续整数,并且这个链比0, 1
更长。如果写作有些不清楚,请谅解,英语不是我的母语。
itertools.groupby
按照递增计数的常量差分成子序列,计数通过一个 itertools.count
对象提供,然后使用内置的 max
函数取最长的子序列,其中的 key 参数为 len
。from itertools import groupby, count
lst = [0, 1, 3, 5, 7, 8, 9, 10, 12, 13]
c = count()
val = max((list(g) for _, g in groupby(lst, lambda x: x-next(c))), key=len)
print(val)
# [7, 8, 9, 10]
_
)以进一步了解它的工作原理。使用 numpy 模块的替代方案:
import numpy as np
nums = np.array([0, 1, 3, 5, 7, 8, 9, 10, 12, 13])
longest_seq = max(np.split(nums, np.where(np.diff(nums) != 1)[0]+1), key=len).tolist()
print(longest_seq)
[7, 8, 9, 10]
np.where(np.diff(nums) != 1)[0]+1
- 获取应该将数组拆分的元素的索引(如果两个连续数字之间的差不等于1
,例如3
和5
)
np.split(...)
- 将数组拆分为子数组
https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.diff.html#numpy.diff https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.split.html
代码
使用 itertools.groupby
(类似于@Moses Koledoye的答案):
groups = [[y[1] for y in g] for k, g in itertools.groupby(enumerate(iterable), key=lambda x: x[0]-x[1])]
groups
# [[0, 1], [3], [5], [7, 8, 9, 10], [12, 13]]
max(groups, key=len)
# [7, 8, 9, 10]
替代方案
考虑使用第三方工具 more_itertools.consecutive_groups
:
import more_itertools as mit
iterable = [0, 1, 3, 5, 7, 8, 9, 10, 12, 13]
max((list(g) for g in mit.consecutive_groups(iterable)), key=len)
# [7, 8, 9, 10]