简体   繁体   English

相互比较列表中的项目

[英]Comparing items within a list with each other

If I have a list 如果我有清单

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

and I want to show that two items exist one of which is larger than the other by 1, can I do this without specifying which items in the list? 并且我想证明存在两个项目,其中一个项目比另一个项目大1,是否可以在指定列表中哪些项目的情况下执行此操作?

ie. 即。 without having to do something like: 无需执行以下操作:

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

a general code that works for any int items in the lst ,在任何INT项目工作有一个大致的代码lst

如果列表中小于数字的数字可以配对:

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

This one: makes set of the list for faster member checks; 这是一个列表集,用于更快的成员检查; then short circuiting checks if i + 1 exists in that set for each i in the list (I iterate over list instead of the newly created set because it should be slightly faster). 然后短路检查列表中每个i集合中是否存在i + 1 (我遍历列表而不是新创建的集合,因为它应该稍快一些)。 As soon as it is proven that any i + 1 also is in the list, the function exits with True return value, False otherwise. 一旦证明任何i + 1也在列表中,该函数将以True返回值退出,否则以False退出。

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

Testing: 测试:

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

The all tricks in 1 basket brain-teaser one: 1个篮子脑筋急转弯的所有技巧:

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

What this code does is: sort the list in increasing order; 该代码的作用是:按递增顺序对列表进行排序; then do the pairwise iteration of a, b = lst[i], lst[i + 1] , then starmaps each b, a into the sub operator resulting in b - a ; 然后对a, b = lst[i], lst[i + 1]进行成对迭代a, b = lst[i], lst[i + 1] ,然后对每个b, a进行星形映射b, a映射到sub运算符中,得到b - a and then checks with in operator if that resulting iterator contains any 1 . 然后使用in运算符检查该结果迭代器是否包含1

You could zip the list with itself shifted by one. 您可以将列表本身拉近一来压缩列表。

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

This assumes that the list is ordered. 这假定列表是有序的。 If it is not, then you could sort it first and then filter it to exclude non matches (perhaps including the indexes in the original list if that is important). 如果不是,那么您可以先对其进行排序,然后对其进行过滤以排除不匹配项(如果重要的话,可以在原始列表中包括索引)。 So if it's a more complex list of integers this should work: 因此,如果它是更复杂的整数列表,则应该可以使用:

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

The following is the equivalent using functions. 以下是等效的using函数。 The use of izip from itertools ensure the list is only iterated over once when we are looking for matches with the filter function: 使用itertoolsizip可以确保当我们使用过滤器功能查找匹配项时,仅将列表重复一次:

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

The same could be written using for comprehensions, but personally I prefer using functions. 可以将相同的内容用于理解,但是我个人更喜欢使用函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM