Reputation: 13
I need to write function that will count how much numbers are ordered in ascending order in a row. for example: we have this list:
L = [2, 4, 5, 6, 7, 2, 3, 2, 2, 2, 8, 7, 5, 6]
and the largest ascending series of numbers are 5.
I've tried:
count=0
def ascord(L,count):
for i in range(0,len(L)-1):
if L[i]<L[i+1]:
count+=1
return count
but the output is 7. I don't know how to "reset" count so it wouldn't take [2,8] and [5,6] into consideration
Edit: I meant that if I for ex. add at the end of list twenty numbers in asc. order they will be largest series of numbers, so the first count should be set to 0, and start counting from start
PS. Sorry for my english.
Upvotes: 0
Views: 849
Reputation: 58291
Your code instead counts the number of pairs in the list L
such that L[i] < L[i + 1]
. The bug is that you do not track the continuity of ascending sub-sequence in the list. For example, while iteration over L
if at some point a condition L[i] >= L[i + 1]
occur then you should reset count
. @Gareth Ma corrected your code. Although, below I have shared my code that will return you max length ascending subsequence in the list L.
Note, while iterating over the L
, cstart
and cend
are index points for the current subsequence. Current subsequence grows until the current value cval
greaser than previous val
— keeps track of increasing value. At the end of each subsequence (either because of iteration exhaust or the current cval
is smaller than previous val
) I compare the lengths of subsequences and rests start
and end
indexes of longest subsequences in L
.
def find_longest_ascending(L):
if len(L) < 2:
return L
I = enumerate(L)
cstart, val = next(I)
start = end = cstart
for cend, cval in I:
if cval <= val:
if end - start < cend - cstart:
start, end = cstart, cend
cstart = cend
val = cval
if end - start < cend - cstart + 1:
start, end = cstart, cend + 1
return L[start: end]
When the longest ascending subsequence is the suffix of the L
(in if-condition outside the for-loop) the cend
do not point out of subsequence hance added 1.
Upvotes: 0
Reputation: 1151
Edited:
Inspired from here.
sub_lst = [0]+[i for i in range(1,len(L)) if L[i] < L[i-1] ]+[None]
print(max(len(x) for x in (L[b:e] for (b, e) in ((0,1) if sub_lst[1] == None else (sub_lst[i-1],sub_lst[i]) for i in range(1,len(sub_lst))))))
Unreadable, I know. Took it as a challenge :)
Upvotes: -2
Reputation: 104092
With groupby
you can find the longest sequence of elements that sort ascending:
L = [2, 4, 5, 6, 7, 2, 3, 2, 2, 2, 8, 7, 5, 6]
from itertools import groupby
sorted_seq=[]
for k,v in groupby(zip(L, L[1:]), key=lambda t:t[0]<t[1]):
if k==True:
temp=list(v)
sorted_seq.append([t[0] for t in temp]+[temp[-1][1]])
>>> sorted_seq
[[2, 4, 5, 6, 7], [2, 3], [2, 8], [5, 6]]
Then take the max
of that with len
as a key:
>>> max(sorted_seq, key=len)
[2, 4, 5, 6, 7]
Then:
>>> len(max(sorted_seq, key=len))
5
Which (if you don't care about dropping the final element of the sorted sequence and adding 1 to compensate) can be a single comprehension:
>>> len(max(([t[0] for t in v] for k,v in groupby(zip(L, L[1:]), key=lambda t:t[0]<t[1]) if k), key=len))+1
5
Upvotes: 1
Reputation: 71
According to your logic, start with
count = 1
instead of
count = 0
Also, use an additional variable to keep track of the max count encountered so far, while traversing through the list. Reset count to 1 when the ascent breaks.
def ascord(L):
count, ans = 1, 1
for i in range(len(L) - 1):
if L[i]<L[i+1]:
count+=1
else:
count=1
ans = max(count, ans)
return ans
Upvotes: 1
Reputation: 707
Cleaned up:
def ascord(L):
answer = 0
count = 1
for i in range(len(L) - 1):
if L[i] < L[i + 1]:
count += 1
else:
if count > answer:
answer = count
count = 1
return max(count, answer)
L = [2, 4, 5, 6, 7, 2, 3, 2, 2, 2, 8, 7, 5, 6]
print (ascord(L)) # 5
cheers :)
Upvotes: 2