检查列表中是否有相邻的整数相等。

3
如果我有一个列表
a = [9,4,3,6,4,4,3,6,4] 

如何检查相邻的两个元素是否相同?例如,对于索引为4和5的元素(它们都具有值4),这将为真。


3
你尝试过使用for循环并检查a[i] == a[i+1]吗? - OneCricketeer
我遇到了一个索引超出范围的错误。 - boson
那么你应该使用 len(a) - 1 作为范围的结尾。 - OneCricketeer
4个回答

5
pairs = zip(a, a[1:]) # Create tuples of neighbours
equals = map(lambda (x, y): x == y, pairs) # List of booleans which tells whether tuple elements are equal or not
hasEqualNeighbours = any(equals) # Is there a True boolean in the list?

或者导入eq函数代替lambda,注意map可以同时迭代多个列表,所以不需要zip

from operator import eq
hasEqualNeigbours = any(map(eq, a, a[1:]))

如果你使用的是Python 2,你还可以使用from future_builtins import map。这会使得map成为一个惰性迭代器而不是构建整个列表对,从而节省内存,同时也可能减少运行时间。


3
在这里使用any会更加直观简单,而且使用带有maplambda总是最糟糕的选择(如果使用C内置的map可能还可以,否则,请使用生成器表达式)。但在这种情况下,map可能更好,完全不需要使用zipoperator.eqfrom operator import eqhasEqualNeighbors = any(map(eq, a, a[1:]))。如果在Python 2上,则需要先执行from future_builtins import map以获取基于生成器的map(这样any可以提前结束并在第一次检查时避免进一步检查)。 - ShadowRanger
谢谢,我只是想避免导入任何东西,但你是完全正确的。我已经更新了我的答案。 - Emil Vikström

5
这是一个关于内存和执行时间效率的高效方法,适用于Python 3.x
import itertools
import operator

if any(map(operator.eq, a, itertools.islice(a, 1, None))):
    print("There are equal neighbhors")

itertools.islice() 创建一个迭代器,它可以切片一个序列而不创建新的序列。 map() 通过使用 operator.eq() 检查每个时间是否相等,从而检查序列中的项目和后面的项目。
any() 然后迭代 map 并返回任意一个为 True 的结果。

对于 Python 2.x,我建议这样做:

import itertools
import operator

if any(itertools.imap(operator.eq, a, itertools.islice(a, 1, None))):
    print("There are equal neighbhors")

由于Python 2.x中的map函数返回列表而不是迭代器。


1
@Christian 添加了完整的解释。 - Bharel

1
我可能会使用 itertools.groupby:
any(len(list(g)) > 1 for k, g in itertools.groupby(a))

这段代码非常直观,但是itertools会将输入的可迭代对象分成值相等的块。我只需要查看是否有任何一个块具有多于1个元素。如果是,则存在相邻重复项。

这个算法的时间复杂度上限/平均时间复杂度为O(N),这是像这样的算法所能希望的最好结果。但是对于某些输入,它可以是O(1),因为它在找到匹配项时立即中断(例如,在可迭代对象的开头发现重复项)。


0

我相信这是最易读的版本:

>>> from itertools import izip
>>> any(first == second for first, second in izip(a, a[1:]))
True

any 的评估是惰性的。通过 izip 按需创建对。如果您使用的是 Python 3,则 zip 已经执行了 Python 2 中 izip 的功能。

解释:

>>> zip(a, a[1:])
[(9, 4), (4, 3), (3, 6), (6, 4), (4, 4), (4, 3), (3, 6), (6, 4)]

将创建相邻元素对的元组。传递给any的是一个生成器表达式,用于检查这些元组中是否有两个相同的元素。

如果您想进一步优化内存效率,请像这样调用(i)zip

>>> it = iter(a)
>>> next(it, None)
9
>>> zip(a, it)
[(9, 4), (4, 3), (3, 6), (6, 4), (4, 4), (4, 3), (3, 6), (6, 4)]

这将避免创建列表 a [1:]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接