Return 列表中第一个元素的索引,增量增加从这里开始

Return the index of the first element in the list from where incremental increase starts

假设我有一个这样的列表,其中数字按不同的步骤增加:

[ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

我想 return 列表中第一个元素的索引,其中增量是递增的(仅 +1 步)。在这种情况下,23 是第一个开始增加的位置,它的索引为 8,这就是我想要的输出。

实现此目标的优雅简单方法是什么?这是我试过的:

>>> for (a,b) in zip(l, l[1:]):
...     if b-a == 1:
...             print(l.index(a))
...             break

更新:在这个特定的设置中,一旦增加成为增量,它将继续保持这种状态。增加可能永远不会成为增量。

对每个循环做一次,并检查以前的值和当前值。一旦达到当前值仅比前一个值大 1 的点,return 数组中前一个值的索引:

myList = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
lastVal = -1000
for i in myList:
    if i - lastVal == 1:
        print(myList.index(lastVal)) #will print your desired value's index. If this is in a function, replace print with return
        break
    lastVal = i
if myList.index(lastVal) == len(myList) - 1:
    print("There is no incremental increase in your array")

(已编辑,将 return 替换为 lastVal,固定打印索引) 输出:

8

这是一种迭代方法。我们可以遍历列表并在每个索引处执行以下操作:

  • 如果当前值是前一个加一,则不移动增量索引
  • 否则,将增量索引重置为当前位置

如果我们到达列表的末尾并且我们有一个比最后一个位置更早的增量索引,那么我们有一个潜在的匹配。

lst = [0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
idx = 0
for i in range(1, len(lst)):
    if lst[i] != lst[i-1] + 1:
        idx = i

if idx < len(lst) - 1:
    print("Found index: " + str(idx) + ", value: " + str(lst[idx]))
else:
    print("No incremental index found")

这会打印:

Found index: 8, value: 23

解决方案 1:operator

from operator import sub, indexOf

L = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

print(indexOf(map(sub, L[1:], L), 1))
# prints 8

如果差异 1 从未发生,则引发 ValueError: sequence.index(x): x not in sequence,因此可能需要为此使用 try/except

解决方案 2:bisect

这个只需要 O(log n) 时间,使用增量的单调性(正如你评论的 “一旦增加成为增量,它将继续保持这种方式”) .

from bisect import bisect

L = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

class IsIncremental:
    def __getitem__(_, i):
        return L[i+1] - L[i] == 1

print(bisect(IsIncremental(), False, 0, len(L) - 1))
# prints 8

如果差异 1 从未发生,则打印 len(L) - 1

顺便说一句...可读性

正如PEP 8所说:

Never use the characters 'l' (lowercase letter el), [...] as single character variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use 'l', use 'L' instead.

步骤:

  1. 迭代数组直到倒数第二个元素。
  2. 检查下一个元素值是否与当前元素值正好相差 1。
  3. 打印索引并打破循环。

代码:

my_list = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
for i in range(len(my_list)-1):
    if my_list[i+1] - my_list[i] == 1:
        print(i)
        break

结果:

8

这里有一种使用列表推导式来做到这一点的方法

lst = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
list2 = [i-1 for i,j in enumerate(lst) if j-lst[i-1]==1] 
if len(list2)>0:
    print(list2[0])
else:
    print('No one up number exists')

与之前的答案类似。

myList = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
l0 = 0 #suppose that the initial value is 0
for l1 in myList:
    increment = l1 - l0
    if increment == 1:
        print(myList.index(l0)) #if you want to get the second element, use l1 instead.
        break #if you want to get all the first elements that has 1 increment, remove break
    l0 = l1 #memorize l1