我想要構建一個函數,如果列表中的任何兩個項目都相同,將返回True。列表中的重複
例如,[1,7,3,7,4]
應返回True
和["one","ONE","One"]
應返回False
。
我需要幫助python的哪些部分查找重複項。
我想要構建一個函數,如果列表中的任何兩個項目都相同,將返回True。列表中的重複
例如,[1,7,3,7,4]
應返回True
和["one","ONE","One"]
應返回False
。
我需要幫助python的哪些部分查找重複項。
將值循環並使用set
來跟蹤您已經看到的內容。只要你看到一個值再次,返回True
:
def has_duplicates(lst):
seen = set()
for elem in lst:
if elem in seen:
return True
seen.add(elem)
return False
這是因爲它短路非常有效;如果早期檢測到重複,它將不會遍歷整個列表。
列表不會更快嗎? ('seen = []')我做了一個快速的'timeit'('timeit.timeit(「s.add(5)」,「s = set()」)''爲'0.100 ...'和'timeit。 timeit(「s.append(5)」,「s = []」)'爲'0.0911') – 2015-02-23 16:30:30
爲什麼不這樣做:'if len(set(lst))!= len(lst)' – RPGillespie 2015-02-23 16:30:31
@RPGillespie因爲必須遍歷整個列表。 – 2015-02-23 16:31:03
Martijn的answer是最好的,但有一些例外,這是值得一試。
>>> chk = lambda x: len(l) != len(set(l)) # check the length after removing dupes.
>>> l = [1,7,3,7,4]
>>> chk(l)
True
>>> l = ["one","ONE","One"]
>>> chk(l)
False
注 - 作爲Martijn提到了一個評論,這是一個緩慢的過程。
這需要遍歷整個*列表。例如,用'[1] + list(range(1000000))'試試這個。 – 2015-02-23 16:28:30
@MartijnPieters是的,這是一個非常緩慢的方式來做! :)(但希望不是*錯誤的方式) – 2015-02-23 16:29:40
使用collections.Counter字典:
from collections import Counter
def has_dupes(l):
# if most repeated key count is > 1 we have at least one dupe
return Counter(l).most_common(1)[0][1] > 1
或者使用any
:
def has_dupes(l):
return any(v > 1 for v in Counter(l).values())
這比使用len(set(l))更慢,因爲它需要一個O(N)循環遍歷所有的值,然後創建一個堆來找到最常見的元素,再次O(N)。漸近地與len(set(l))相同,但每次迭代的固定成本較高。 – 2015-02-23 16:52:03
@MartijnPieters,是的,但是一個線性的解決方案,另一個如何做OP的想法和一個Counter dict的介紹,這是一個非常有用的工具。如果問題是什麼是最佳的方式,因爲我有大量的數據,那麼這將是不同的,但事實並非如此。 – 2015-02-23 16:54:36
我只是在評論解決方案的性能方面,因爲我認爲這很重要。否則,這整個問題只會是[在Python中的列表中識別重複值](http://stackoverflow.com/q/11236006) – 2015-02-23 16:57:32
相關:[識別在Python列表重複值(http://stackoverflow.com/q/11236006 ) – 2015-02-23 16:27:55