比较列表中的项目

Comparing items within a list with each other

如果我有一个列表

lst = [1, 2, 3, 4, 5]

并且我想证明存在两个项目,其中一个比另一个大 1,我可以这样做 而不 指定列表中的哪些项目吗?

即。无需执行以下操作:

lst[1] - lst[0] == 1 

适用于 lst

中任何整数项的通用代码

如果列表中小于该号码的号码,您可以将号码配对:

new = [(i, i - 1) for i in lst if i - 1 in lst]

您可以将列表本身移位一位进行压缩。

>>> lst = [1,2,3,4,5]
>>> zip(lst, lst[1:])
[(1, 2), (2, 3), (3, 4), (4, 5)]

这假设列表是有序的。如果不是,那么您可以先对其进行排序,然后对其进行过滤以排除不匹配项(如果这很重要,可能包括原始列表中的索引)。因此,如果它是一个更复杂的整数列表,这应该有效:

>>> lst = [99,12,13,44,15,16,45,200]
>>> lst.sort()
>>> [(x,y) for (x,y) in zip(lst, lst[1:]) if x + 1 == y]
[(12, 13), (15, 16), (44, 45)]

下面是等价的using函数。使用 itertools 中的 izip 确保列表仅在我们使用过滤器函数查找匹配项时迭代一次:

>>> from itertools import izip
>>> lst = [99,12,13,44,15,16,45,200]
>>> lst.sort()
>>> filter(lambda (x,y): x+1==y, izip(lst, lst[1:]))
[(12, 13), (15, 16), (44, 45)]

同样可以使用 for comprehensions 来编写,但我个人更喜欢使用函数。

这个:制作一组列表以加快成员检查;然后短路检查列表中每个 i 的集合中是否存在 i + 1(我遍历列表而不是新创建的集合,因为它应该稍微快一些)。一旦证明任何 i + 1 也在列表中,函数将以 True return 值退出,否则 False

def has_n_and_n_plus_1(lst):
    lset = set(lst)
    return any(i + 1 in lset for i in lst)

测试:

>>> has_n_and_n_plus_1([6,2,7,11,42])
True
>>> has_n_and_n_plus_1([6,2,9,11,42])
False

一篮子脑筋急转弯一:

from operator import sub
from itertools import starmap, tee

a, b = tee(sorted(lst))
next(b, None)
exists = 1 in starmap(sub, zip(b, a))

这段代码的作用是:对列表进行升序排序;然后进行 a, b = lst[i], lst[i + 1] 的成对迭代,然后将每个 b, a 星图映射到 sub 运算符中,得到 b - a;然后使用 in 运算符检查生成的迭代器是否包含任何 1.