【问题标题】:How can I find the longest contiguous subsequence in a rising sequence in Python?如何在 Python 的上升序列中找到最长的连续子序列?
【发布时间】:2021-12-11 17:39:52
【问题描述】:

我需要在 Python 的上升序列中找到最长的连续子序列。

例如,如果我有A = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 25, 27, 28, 29, 30]

答案是 [17, 18, 19, 20, 21],因为它是最长的连续子序列,有 5 个数字(而 [1, 2, 3]3 数字长,[27, 28, 29, 30]4 数字长。)

我的代码陷入了死循环

num_list = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 23, 25, 26, 27]
longest_sequence = {}
longest_sequence_length = 1
for num in num_list:
    sequence_length = 1
    while True:
        if (num + sequence_length) in num_list:
            sequence_length += 1
        else:
            if sequence_length > longest_sequence_length:
                longest_sequence_length_length = sequence_length
                longest_sequence = {"start": num, "end": num + (sequence_length - 1)}
        break
print(f"The longest sequence is {longest_sequence_length} numbers long"
      f" and it's between {longest_sequence['start']} and {longest_sequence['end']}")

【问题讨论】:

  • while 循环内我没有看到任何跳出循环的语句(如breakreturn)。
  • 放中断,而不是放错位置的继续。现在它可以工作,但不能真正搜索。

标签: python list subsequence


【解决方案1】:

你可以用numpy一行来解决:

import numpy as np
A = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 25, 27, 28, 29, 30]
out = max(np.split(A, np.where(np.diff(A) != 1)[0] + 1), key=len).tolist()

您也可以通过运行 3 次迭代来找到相同的结果。

(i) 首先你需要找到A中连续元素之间的差异;在diff 中找到(使用zip(A,A[1:]),您可以访问连续元素)。

(ii) 然后你将A 拆分为差异不为 1 的索引;这是在第二次迭代中完成的。基本上,如果差值为1,则将A中的值附加到正在运行的子列表中,如果没有,则创建一个新的子列表并将对应的值放入这个新的子列表中。

(iii) 最后,使用max() 函数,您可以使用key=len 找到最长的子列表。

同样的工作由上面的numpy 代码完成。

diff = [j-i for i,j in zip(A, A[1:])]
splits = [[A[0]]]
for x,d in zip(A[1:], diff):
    if d == 1:
        splits[-1].append(x)
    else:
        splits.append([x])
out = max(splits, key=len)

输出:

[17、18、19、20、21]

【讨论】:

  • 很棒的解决方案。
  • 对于这么优雅的解决方案,恐怕我太新手了,您能推荐一个更简化的解决方案吗?
  • @swapman 我编辑添加了一个更直观的解决方案。您可以解决类似的问题,以测试您将来是否可以做类似的事情,例如找到数字跳过 2 等的最长序列。
  • 非常感谢。会尝试自己处理,看看我能完全理解你的代码。
【解决方案2】:

在第 13 行中,您需要一个 break 而不是 continue 语句。

另外,在第 11 行你有一个小错误,在你的变量名中添加了一个额外的“_length”。

【讨论】:

  • 谢谢,确实是'break'。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多