Überprüfen Sie auf Duplikate in einer flachen Liste

Beispiel 1

['one', 'two', 'one'] sollte True .

Beispiel 2

['one', 'two', 'three'] sollte False .

5 Solutions collect form web for “Überprüfen Sie auf Duplikate in einer flachen Liste”

Verwenden Sie set() , um Duplikate zu entfernen, wenn alle Werte hashable sind :

 >>> your_list = ['one', 'two', 'one'] >>> len(your_list) != len(set(your_list)) True 

Empfohlen nur für Kurzlisten:

 any(thelist.count(x) > 1 for x in thelist) 

Verwenden Sie nicht auf eine lange Liste – es kann Zeit nehmen proportional zum Quadrat der Anzahl der Artikel in der Liste!

Für längere Listen mit Hash-Items (Strings, Zahlen & C):

 def anydup(thelist): seen = set() for x in thelist: if x in seen: return True seen.add(x) return False 

Wenn Ihre Artikel nicht hashable sind (Sublisten, Dicts, etc.) wird es haariger, obwohl es immer noch möglich ist, O (N logN) zu bekommen, wenn sie zumindest vergleichbar sind. Aber du musst die Eigenschaften der Items (hashable oder nicht, vergleichbar oder nicht) kennen oder testen, um die beste Leistung zu erhalten, die du kannst – O (N) für Hashables, O (N log N) für nicht-haltbare Vergleiche, sonst Es ist bis zu O (N quadriert) und es gibt nichts, was man dagegen tun kann :-(.

Das ist alt, aber die Antworten hier führten mich zu einer etwas anderen Lösung. Wenn Sie sich für Missbrauch von Verständnissen einsetzen, können Sie sich auf diese Weise kurzschließen.

 xs = [1, 2, 1] s = set() any(x in s or s.add(x) for x in xs) # You can use a similar approach to actually retrieve the duplicates. s = set() duplicates = set(x for x in xs if x in s or s.add(x)) 

Wenn Sie gern funktionalen Programmierstil sind, hier ist eine nützliche Funktion, selbst dokumentiert und getestet Code mit doctest .

 def decompose(a_list): """Turns a list into a set of all elements and a set of duplicated elements. Returns a pair of sets. The first one contains elements that are found at least once in the list. The second one contains elements that appear more than once. >>> decompose([1,2,3,5,3,2,6]) (set([1, 2, 3, 5, 6]), set([2, 3])) """ return reduce( lambda (u, d), o : (u.union([o]), d.union(u.intersection([o]))), a_list, (set(), set())) if __name__ == "__main__": import doctest doctest.testmod() 

Von dort aus können Sie Unicity testen, indem Sie überprüfen, ob das zweite Element des zurückgegebenen Paares leer ist:

 def is_set(l): """Test if there is no duplicate element in l. >>> is_set([1,2,3]) True >>> is_set([1,2,1]) False >>> is_set([]) True """ return not decompose(l)[1] 

Beachten Sie, dass dies nicht effizient ist, da Sie explizit die Zerlegung konstruieren. Aber entlang der Linie der Verwendung reduzieren, können Sie bis zu etwas Äquivalent (aber etwas weniger effizient) zu beantworten 5:

 def is_set(l): try: def func(s, o): if o in s: raise Exception return s.union([o]) reduce(func, l, set()) return True except: return False 

Ich habe vor kurzem eine verwandte Frage beantwortet, um alle Duplikate in einer Liste zu erstellen, mit einem Generator. Es hat den Vorteil, dass wenn nur verwendet, um zu etablieren, "wenn es ein Duplikat" dann müssen Sie nur das erste Element zu bekommen und der Rest kann ignoriert werden, was ist die ultimative Verknüpfung.

Dies ist ein interessanter Set-basierter Ansatz, den ich direkt von moooeeeep anpasste :

 def getDupes(l): seen = set() seen_add = seen.add for x in l: if x in seen or seen_add(x): yield x 

Dementsprechend wäre eine vollständige Liste von Dups list(getDupes(etc)) . Um einfach zu testen "wenn" gibt es einen Dummkopf, sollte es wie folgt gewickelt werden:

 def hasDupes(l): try: if getDupes(c).next(): return True # Found a dupe except StopIteration: pass return False 

Diese Skala gut und bietet konsequente Betriebszeiten, wo immer der Dupe in der Liste ist – ich habe mit Listen von bis zu 1m Einträgen getestet. Wenn Sie etwas über die Daten wissen, speziell, dass Dups sind wahrscheinlich zu zeigen, in der ersten Hälfte, oder andere Dinge, die Sie skew Ihre Anforderungen, wie die Notwendigkeit, die tatsächlichen Dummes zu bekommen, dann gibt es ein paar wirklich alternative Dupe Locators Das könnte übertreffen Die beiden empfehle ich …

Einfacher dict-basierter Ansatz, sehr lesbar:

 def getDupes(c): d = {} for i in c: if i in d: if d[i]: yield i d[i] = False else: d[i] = True 

Heben Sie itertools (im Wesentlichen ein ifilter / izip / tee) auf der sortierten Liste, sehr effizient, wenn Sie alle Dups bekommen, aber nicht so schnell, um nur die erste zu bekommen:

 def getDupes(c): a, b = itertools.tee(sorted(c)) next(b, None) r = None for k, g in itertools.ifilter(lambda x: x[0]==x[1], itertools.izip(a, b)): if k != r: yield k r = k 

Dies waren die Top-Performer aus den Ansätzen, die ich für die volle Dupe-Liste versuchte, mit dem ersten Dupe, der irgendwo in einer 1m-Elementliste von Anfang bis Mitte auftritt. Es war überraschend, wie wenig oben die Art Schritt hinzugefügt wurde. Ihre Meilenzahl kann variieren, aber hier sind meine spezifischen zeitlichen Ergebnisse:

 Finding FIRST duplicate, single dupe places "n" elements in to 1m element array Test set len change : 50 - . . . . . -- 0.002 Test in dict : 50 - . . . . . -- 0.002 Test in set : 50 - . . . . . -- 0.002 Test sort/adjacent : 50 - . . . . . -- 0.023 Test sort/groupby : 50 - . . . . . -- 0.026 Test sort/zip : 50 - . . . . . -- 1.102 Test sort/izip : 50 - . . . . . -- 0.035 Test sort/tee/izip : 50 - . . . . . -- 0.024 Test moooeeeep : 50 - . . . . . -- 0.001 * Test iter*/sorted : 50 - . . . . . -- 0.027 Test set len change : 5000 - . . . . . -- 0.017 Test in dict : 5000 - . . . . . -- 0.003 * Test in set : 5000 - . . . . . -- 0.004 Test sort/adjacent : 5000 - . . . . . -- 0.031 Test sort/groupby : 5000 - . . . . . -- 0.035 Test sort/zip : 5000 - . . . . . -- 1.080 Test sort/izip : 5000 - . . . . . -- 0.043 Test sort/tee/izip : 5000 - . . . . . -- 0.031 Test moooeeeep : 5000 - . . . . . -- 0.003 * Test iter*/sorted : 5000 - . . . . . -- 0.031 Test set len change : 50000 - . . . . . -- 0.035 Test in dict : 50000 - . . . . . -- 0.023 Test in set : 50000 - . . . . . -- 0.023 Test sort/adjacent : 50000 - . . . . . -- 0.036 Test sort/groupby : 50000 - . . . . . -- 0.134 Test sort/zip : 50000 - . . . . . -- 1.121 Test sort/izip : 50000 - . . . . . -- 0.054 Test sort/tee/izip : 50000 - . . . . . -- 0.045 Test moooeeeep : 50000 - . . . . . -- 0.019 * Test iter*/sorted : 50000 - . . . . . -- 0.055 Test set len change : 500000 - . . . . . -- 0.249 Test in dict : 500000 - . . . . . -- 0.145 Test in set : 500000 - . . . . . -- 0.165 Test sort/adjacent : 500000 - . . . . . -- 0.139 Test sort/groupby : 500000 - . . . . . -- 1.138 Test sort/zip : 500000 - . . . . . -- 1.159 Test sort/izip : 500000 - . . . . . -- 0.126 Test sort/tee/izip : 500000 - . . . . . -- 0.120 * Test moooeeeep : 500000 - . . . . . -- 0.131 Test iter*/sorted : 500000 - . . . . . -- 0.157 
  • Python, Reinigung einer Liste
  • Überprüfen Sie, ob String in Python oberer, niedrigerer oder gemischter Fall ist
  • Wie man bedingten Charakter Ersatz in einem String zu tun
  • Iterate über die Zeilen einer Saite
  • Mehrere Vorkommen eines Strings innerhalb eines Strings in Python finden
  • Wie man einzelne Anführungszeichen in Python auf dem Server entschlüsselt, um in Javascript auf Client verwendet zu werden
  • Python konvertiert String zu float
  • Python konvertieren String Literal zu Float
  • Grund python string
  • Python: Zahlen aus einer Zeichenfolge extrahieren
  • Python - Konvertierung von String in Liste
  • Python ist die beste Programmiersprache der Welt.