簡體   English   中英

查找列表中的第一個元素,其中所有后續值都遞增一個

[英]Find the first element in a list where all subsequent values increment by one

我想在列表中找到該值,之后所有其他值僅增加 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

我正在考慮在列表中向后循環,當減少量大於 1 時,在此 position 處提取值。

for x in reversed(my_list1):
    if x decrease > 1:
        print(x)

這是一個基於itertools的工具,如果我們有一個長的列表很有用,所以我們沒有將它加載到 memory 中。 這里dropwhile將在條件成立時從可迭代對象中刪除值,我們只需要獲取結果可迭代對象中的next元素。 請注意, 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

您可以將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,
    )

為了避免next()在沒有找到結果並且迭代器耗盡時返回StopIteration ,我們可以將默認值設置為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

列表推導有幾種可能性。 在這里,我收集每個增加超過 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])

好吧,我試過了,它奏效了,但也許還有更好、更有效的解決方案,

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

這是一個沒有重復代碼的解決方案:

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))

這是一個基本的基於循環的實現。

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

這是我的嘗試:

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

這個怎么運作:

# tmplist is [2, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

重復數字顯示原始列表中增加序列(+1)的位置。 最后一項 ( tmplist[-1] ) 是 6,我們想要獲得第一個此類項目 ( tmplist.index(...) ) 的 position,因為序列從那里開始。 最后,我們查找該索引處的值( my_list1[...]

基於序列中缺失數字的拆分列表類似,您可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM