比较列表中的项目
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
.
如果我有一个列表
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
.