2016-03-31 78 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:]