简体   繁体   中英

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?

ie. without having to do something like:

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

a general code that works for any int items in the 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). As soon as it is proven that any i + 1 also is in the list, the function exits with True return value, False otherwise.

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:

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 ; and then checks with in operator if that resulting iterator contains any 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. The use of izip from itertools ensure the list is only iterated over once when we are looking for matches with the filter function:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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