Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
最长连续子序列的Pythonic方法_Python - Fatal编程技术网

最长连续子序列的Pythonic方法

最长连续子序列的Pythonic方法,python,Python,我在一个名为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

我在一个名为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 

我觉得这可以在智能的一行或两行中完成,您可以使用和执行以下操作:

以下内容仍然可以阅读;-并为您提供一个体面的中间步骤,从中以更明智的方式进行可能是一个有效的选择:

max((list(g) for k, g in groupby(zip(l, l[1:]), key=f) if k), key=len)
# [(5, 6), (6, 7), (7, 8)]
为了在一行中提取actaul所需的序列[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]
我将让你们来研究这个怪物的内部结构:-但请记住:一行代码通常在短期内是令人满意的,但从长期来看,更好地选择可读性和代码,您和您的同事将理解。可读性是你提到的Pythonicity的一个重要部分

还请注意,这是因为排序的缘故。您可以通过对链的输出应用一种重复移除技术(例如,OrderedDict)并保持其持续,来实现相同的效果,但这一行会变得更长

更新: 其中一种方法是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

将[5,6,6,7,7,8]转换为5,9,然后进行范围*5,9,成本更低,因为原始列表中的数字是排序的,而且每个组都是连续的,所以范围*g[0][0],g[-1][1]会比sortedsetchain*低一些,但似乎对此解释得不够好。不需要删除重复项,因为它们仅由链生成,在链中也可以通过不生成来删除它们。@DanD。是的,我在回答中提到有更聪明的方法可以从那个阶段开始。据我所知,它们中的大多数(也有很多)与您的类似,都需要将中间结果赋给一个变量,以便访问它的不同部分。纯粹出于学术目的,我将把它放在一行中,保持原样@丹德。我把你的建议更新了。@DanD和schwobaseggl:谢谢你们两个!我不知道groupby方法。首先按黑白像素分组,然后过滤最长的黑色运行时间,这就是我的工作。不是两行,但仍然可读,足够优雅-
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]