如果我有一個列表檢查是否在列表中的任意相鄰的整數相等
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'。 –