I need to find the longest contiguous subsequence in a rising sequence in Python.
For example if I have A = [1, 2, 3, 5, 8, 9, 11, 13, 17, 18, 19, 20, 21, 25, 27, 28, 29, 30]
The answer would be [17, 18, 19, 20, 21]
because it's the longest contiguous subsequence with 5 numbers (whereas [1, 2, 3]
is 3
numbers long and [27, 28, 29, 30]
is 4
numbers long.)
My code is stuck in an endless loop
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']}")
CodePudding user response:
You can use numpy
to solve it in one line:
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()
You can also find the same outcome by running 3 iterations.
(i) First you need to find the differences between consecutive elements in A
; that's found in diff
(with zip(A
,A[1:])
, you can access consecutive elements).
(ii) Then you split A
on indices where the difference is not 1; that's being done in the second iteration. Basically, if a difference is 1, append the value in A
to the running sublist, if not, create a new sublist and put the corresponding value to this new sublist.
(iii) Finally, using max()
function, you can find the longest sublist using key=len
.
This exact same job is done by the numpy
code above.
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)
Output:
[17, 18, 19, 20, 21]
CodePudding user response:
In line 13 you need a break instead of a continue statement.
Also, in line 11 you had a little mistake, added an extra "_length" to you variable name.