2016-03-31 40 views
1

如果我有一个列表检查是否在列表中的任意相邻的整数相等

a = [9,4,3,6,4,4,3,6,4] 

我怎么能检查是否有任何两个相邻的元素是一样的吗? 例如,对于索引4和5中的元素(它们都具有值4),这将是正确的。

+3

您是否尝试过for循环并检查'a [i] == a [i + 1]'? –

+0

我得到的索引超出范围错误 – boson

+0

那么你应该在范围的末尾使用'len(a) - 1'。 –

回答

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功能及使用方法,而不是拉姆达,并认识到map可以多个列表遍历一次,所以你不需要zip

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

您也可以嫌上一个from future_builtins import map,如果你在Python 2.这使得map一个懒惰的迭代器,而不是建立对的整个列表,节省你的RAM和可能的运行时间。

+2

在这里使用'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

+0

谢谢,我只是想避免导入任何东西,但你绝对正确。更新了我的答案。 –

3

关于内存和执行时间,这是一个针对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的事实地图返回一个列表,而不是一个迭代器。

+1

@Christian补充说明。 – Bharel

+0

@mgilson完成,谢谢:-) – 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已经做什么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:]