[英]How can I find the longest contiguous subsequence in a rising sequence in Python?
[英]Pythonic way for longest contiguous subsequence
我在名为“ black”的列表中有一个完整的整数列表,并且我正在寻找一种优雅的方式来获得最长连续子序列的“ s”和“ e”开头(原始问题是wxh-位图,我在给定的列x中寻找最长的线。 我的解决方案可行,但看起来很丑:
# blacks is a list of integers generated from a bitmap this way:
# blacks= [y for y in range(h) if bits[y*w+x]==1]
longest=(0,0)
s=blacks[0]
e=s-1
for i in blacks:
if e+1 == i: # Contiguous?
e=i
else:
if e-s > longest[1]-longest[0]:
longest = (s,e)
s=e=i
if e-s > longest[1]-longest[0]:
longest = (s,e)
print longest
我觉得这可以用一个或两个聪明的班轮完成
您可以使用itertools.groupby
和itertools.chain
进行以下操作:
from itertools import groupby, chain
l = [1, 2, 5, 6, 7, 8, 10, 11, 12]
f = lambda x: x[1] - x[0] == 1 # key function to identify proper neighbours
以下内容仍是几乎可读的;-),并为您提供了一个不错的中间步骤,以更明智的方式进行操作可能是有效的选择:
max((list(g) for k, g in groupby(zip(l, l[1:]), key=f) if k), key=len)
# [(5, 6), (6, 7), (7, 8)]
为了在一行中提取实际的所需序列[5, 6, 7, 8]
5、6、7、8 [5, 6, 7, 8]
,您必须使用更多的功夫:
sorted(set(chain(*max((list(g) for k, g in groupby(zip(l, l[1:]), key=f) if k), key=len))))
# [5, 6, 7, 8]
我会留给您解决这种怪异的内部问题:-),但要记住:单线通常在短期内令人满意,但从长远来看,更好地选择了您和您的合作伙伴的可读性和代码工人会明白的。 可读性是您所暗示的Pythonic的重要组成部分。
还请注意,由于排序,这是O(log_N)
。 您可以通过将O(N)
重复删除技术中的一种O(N)
例如涉及OrderedDict
应用于chain
的输出并将其保持为O(N)
,但是那一行会更长。
O(N)
实现方法是DanD。的建议,可以使用理解技巧在一行中使用该建议,以避免将中间结果分配给变量:
list(range(*[(x[0][0], x[-1][1]+1) for x in [max((list(g) for k, g in groupby(zip(l, l[1:]), key=f) if k), key=len)]][0]))
# [5, 6, 7, 8]
更漂亮,但是,它不是:D
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.