[英]Find the first element in a list where all subsequent values increment by one
I would like to find the value in a list, after which all other values increase by 1 only.我想在列表中找到该值,之后所有其他值仅增加 1。
# 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.我正在考虑在列表中向后循环,当减少量大于 1 时,在此 position 处提取值。
for x in reversed(my_list1):
if x decrease > 1:
print(x)
Here's an itertools
based one, useful if we have a very long list, so we don't have load it into memory.这是一个基于
itertools
的工具,如果我们有一个很长的列表很有用,所以我们没有将它加载到 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.这里
dropwhile
将在条件成立时从可迭代对象中删除值,我们只需要获取结果可迭代对象中的next
元素。 Note that next
has a default argument, which we can just set to None
to avoid having the StopIteration
error being raised:请注意,
next
有一个默认参数,我们可以将其设置为None
以避免引发StopIteration
错误:
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
You could zip()
thereversed()
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.您可以将
reversed()
列表zip()
成对,然后使用next()
获取差异大于 1 的第一对。然后我们可以从结果中解压缩第一项。
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
.为了避免
next()
在没有找到结果并且迭代器耗尽时返回StopIteration
,我们可以将默认值设置为None
。
Output: 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
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:
在这里,我收集每个增加超过 1 的数字,将它们存储在列表中并显示最后一个:
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])
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
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))
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
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.重复数字显示原始列表中增加序列(+1)的位置。 Last item (
tmplist[-1]
) is 6, we want to get the position of the first such item ( tmplist.index(...)
), because there the sequence starts.最后一项 (
tmplist[-1]
) 是 6,我们想要获得第一个此类项目 ( tmplist.index(...)
) 的 position,因为序列从那里开始。 Finally we look up the value at that index ( my_list1[...]
)最后,我们查找该索引处的值(
my_list1[...]
)
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:与基于序列中缺失数字的拆分列表类似,您可以使用
itertools.groupby
对数字的连续运行进行分组,并从那里获取最后一次运行的第一个值:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.