Reputation: 147
I would like to find the value in a list, after which all other values increase by 1 only.
# Input
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
my_list2 = [6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28]
my_list3 = [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25]
# Output
my_list1 = 15
my_list2 = 20
my_list3 = 18
I was thinking about looping backwards through the lists and when the decrease is larger than 1, extract the value at this position.
for x in reversed(my_list1):
if x decrease > 1:
print(x)
Upvotes: 1
Views: 1555
Reputation: 88276
Here's an itertools
based one, useful if we have a very long list, so we don't have load it into memory. Here dropwhile
will drop values from the iterable while the condition holds, we only need to take the next
element in the resulting iterable. Note that next
has a default argument, which we can just set to None
to avoid having the StopIteration
error being raised:
from itertools import tee, dropwhile
def first_diff(it):
i, j = tee(reversed(it), 2)
next(j)
return next((dropwhile(lambda e: e==(next(j)+1), i)), None)
first_diff(my_list1)
# 15
first_diff(my_list2)
# 20
first_diff(my_list3)
# 18
Upvotes: 5
Reputation: 13727
Similar to the Splitting list based on missing numbers in a sequence, you can use itertools.groupby
to group consecutive runs of numbers, and from there to get the first value of the last run:
from itertools import groupby
my_list = [2, 5, 7,8,9,10,11,12,13, 15,16,17,18,19,20,21,22,23,24]
first_value = None
for _, group in groupby(enumerate(my_list), lambda x: x[1] - x[0]):
first_value = next(group)[1]
print(first_value)
# 15
Upvotes: 0
Reputation: 26315
You could zip()
the reversed()
lists into pairs, then use next()
to get the first pair where the difference is greater than 1. We can then unpack the first item from the result.
def first_diff_pair(lst):
return next(
(fst for fst, snd in zip(reversed(lst), reversed(lst[:-1])) if fst - snd > 1),
None,
)
To avoid next()
returning StopIteration
when no result is found and the iterator is exhausted, we can set the default value to None
.
Output:
>>> first_diff_pair([2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
15
>>> first_diff_pair([6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28])
20
>>> first_diff_pair([5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25])
18
Upvotes: 2
Reputation: 4273
Here is a basic loop-based implementation.
def get_first_diff(my_list):
reversed_iter = reversed(my_list)
last = next(reversed_iter)
for v in reversed_iter:
if last - v != 1:
return last
last = v
return None
Upvotes: 1
Reputation: 17332
Here is my attempt:
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
tmplist = [x - i for i, x in enumerate(my_list1)]
first = my_list1[tmplist.index(tmplist[-1])]
# result 15
How it works:
# tmplist is [2, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
Repeating numbers show places of increasing sequences (by +1) in the original list. Last item (tmplist[-1]
) is 6, we want to get the position of the first such item (tmplist.index(...)
), because there the sequence starts. Finally we look up the value at that index (my_list1[...]
)
Upvotes: 0
Reputation: 7109
This is a solution with no duplicate code:
my_list1 = [2, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
my_list2 = [6, 7, 9, 11, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28]
my_list3 = [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25]
def getIncreaseStartPoint(nums):
i = len(nums) - 1
while (nums[i] - nums[i - 1] == 1):
i -= 1
if (i == 0):
return nums[0]
return nums[i]
print("mylist_1 =", getIncreaseStartPoint(my_list1))
print("mylist_2 =", getIncreaseStartPoint(my_list2))
print("mylist_3 =", getIncreaseStartPoint(my_list3))
Upvotes: 0
Reputation: 95
Well, I tried this, and it worked, but there maybe better and more efficient solutions to it too,
l = len(my_list1) - 1
for x in reversed(my_list1):
if my_list1[l] - my_list1[l - 1] == 1:
l -= 1
continue
else:
print(x)
break
Upvotes: 1
Reputation: 3315
There are several possibilities with list comprehensions. Here I collect every number that increased by more then one, store them in a list and show the last one:
print([my_list1[i+1] for i in range(len(my_list1)-1) if my_list1[i+1] - my_list1[i] > 1][-1])
print([my_list2[i+1] for i in range(len(my_list2)-1) if my_list2[i+1] - my_list2[i] > 1][-1])
print([my_list3[i+1] for i in range(len(my_list3)-1) if my_list3[i+1] - my_list3[i] > 1][-1])
Upvotes: 1