如果我有一个列表检查是否在列表中的任意相邻的整数相等
a = [9,4,3,6,4,4,3,6,4]
我怎么能检查是否有任何两个相邻的元素是一样的吗? 例如,对于索引4和5中的元素(它们都具有值4),这将是正确的。
如果我有一个列表检查是否在列表中的任意相邻的整数相等
a = [9,4,3,6,4,4,3,6,4]
我怎么能检查是否有任何两个相邻的元素是一样的吗? 例如,对于索引4和5中的元素(它们都具有值4),这将是正确的。
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
功能及使用方法,而不是拉姆达,并认识到map可以多个列表遍历一次,所以你不需要zip
:
from operator import eq
hasEqualNeigbours = any(map(eq, a, a[1:]))
您也可以嫌上一个from future_builtins import map
,如果你在Python 2.这使得map
一个懒惰的迭代器,而不是建立对的整个列表,节省你的RAM和可能的运行时间。
在这里使用'any'更简单一些,'map'使用'lambda'总是最糟糕的选择(使用C builtin的'map'可以很好,否则使用生成器表达式)。在这种情况下,'map'可以更好地工作,根本不需要'zip'' operator.eq':'from operator import eq','hasEqualNeighbors = any(map(eq,a,a [1:]) ))'。如果在Python 2上,首先执行'from future_builtins import map'来获取基于'map'的生成器(这样'任何'都可以提早出来,并避免一旦碰撞就进一步检查)。 – ShadowRanger
谢谢,我只是想避免导入任何东西,但你绝对正确。更新了我的答案。 –
关于内存和执行时间,这是一个针对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()
然后遍历地图并返回(如果有的话)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的事实地图返回一个列表,而不是一个迭代器。
我可能会使用一个itertools.groupby
:
any(len(list(g)) > 1 for k, g in itertools.groupby(a))
的代码是相当简单的,但itertools
将采取输入迭代,并分解成块,其中值相等。我只是看看是否有任何块有超过1个元素。如果是,那么你有相邻的重复。
这有一个上限/平均时间复杂度为O(N),这是最好的,你可以希望这样的算法。对于一些输入,它可以是O(1),因为它一找到匹配就会短路(例如在迭代开始时重复)。
我相信这是最可读的版本:
>>> from itertools import izip
>>> any(first == second for first, second in izip(a, a[1:]))
True
的any
评估会偷懒。对由izip
按需创建。如果您在使用Python 3,zip
已经做什么izip
确实在Python 2
说明:
>>> 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:]
。
您是否尝试过for循环并检查'a [i] == a [i + 1]'? –
我得到的索引超出范围错误 – boson
那么你应该在范围的末尾使用'len(a) - 1'。 –