返回列表中第一个元素的索引,从增量增加开始的位置

Cle*_*lee 4 python indexing list

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

[ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
Run Code Online (Sandbox Code Playgroud)

我想返回列表中第一个元素的索引,其中增量是增量的(仅+1步)。在本例中,23 是第一个位置,从该点开始增量变为增量,其索引为 8,这就是我想要的输出。

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

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

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

Kel*_*ndy 6

解决方案一: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
Run Code Online (Sandbox Code Playgroud)

如果差异 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
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句...可读性

正如PEP 8所说:

切勿使用字符“l”(小写字母 el)、[...] 作为单字符变量名称。在某些字体中,这些字符与数字 1 和 0 无法区分。当想要使用“l”时,请改用“L”。