![](/img/trans.png)
[英]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.