In Anbetracht der Liste ['one', 'two', 'one']
sollte der Algorithmus beispielsweise zurückkehren True
, während er in der gegebenen Liste zurückkehren ['one', 'two', 'three']
sollte False
.
python
string
list
duplicates
teggy
quelle
quelle
Empfohlen für kurze Listen nur:
Sie nicht verwenden , um auf einer langen Liste - es ist Zeit proportional zum nehmen Quadrat der Anzahl der Elemente in der Liste!
Für längere Listen mit hashbaren Elementen (Zeichenfolgen, Zahlen usw.):
Wenn Ihre Artikel nicht hashbar sind (Unterlisten, Diktate usw.), wird es haariger, obwohl es möglicherweise immer noch möglich ist, O (N logN) zu erhalten, wenn sie zumindest vergleichbar sind. Sie müssen jedoch die Eigenschaften der Elemente kennen oder testen (hashbar oder nicht, vergleichbar oder nicht), um die bestmögliche Leistung zu erzielen - O (N) für Hashables, O (N log N) für nicht hashable Vergleiche, andernfalls es liegt an O (N im Quadrat) und man kann nichts dagegen tun :-(.
quelle
all
Zähler ) ist natürlich viel langsamer (benötigt eine Anzahl, bei der alle 1 sind). Ein Diktat mit allen Werten Wahr, das Sie auch erwähnen, ist eine lächerliche, nutzlos aufgeblähte Nachahmung von aset
, ohne jeglichen Mehrwert. Big-O ist nicht alles in der Programmierung.Das ist alt, aber die Antworten hier haben mich zu einer etwas anderen Lösung geführt. Wenn Sie bereit sind, Verständnis zu missbrauchen, können Sie auf diese Weise einen Kurzschluss bekommen.
quelle
Wenn Sie den funktionalen Programmierstil mögen , finden Sie hier eine nützliche Funktion, selbstdokumentierten und getesteten Code mit doctest .
Von dort aus können Sie die Einheitlichkeit testen, indem Sie prüfen, ob das zweite Element des zurückgegebenen Paares leer ist:
Beachten Sie, dass dies nicht effizient ist, da Sie die Zerlegung explizit erstellen. Bei der Verwendung von Reduzieren können Sie jedoch zu einem äquivalenten (aber etwas weniger effizienten) Ergebnis kommen, um 5 zu beantworten:
quelle
Ich dachte, es wäre nützlich, die Zeitabläufe der verschiedenen hier vorgestellten Lösungen zu vergleichen. Dafür habe ich meine eigene Bibliothek benutzt
simple_benchmark
:In diesem Fall ist die Lösung von Denis Otkidach also am schnellsten.
Einige der Ansätze weisen auch eine viel steilere Kurve auf. Dies sind die Ansätze, die quadratisch mit der Anzahl der Elemente skalieren (Alex Martellis erste Lösung, wjandrea und beide Xavier Decorets-Lösungen). Ebenfalls wichtig zu erwähnen ist, dass die Pandas-Lösung von Keiku einen sehr großen konstanten Faktor hat. Bei größeren Listen holt es jedoch fast die anderen Lösungen ein.
Und falls sich das Duplikat an erster Stelle befindet. Dies ist nützlich, um festzustellen, welche Lösungen kurzschließen:
Hier schließen einige Ansätze nicht kurz: Kaiku, Frank, Xavier_Decoret (erste Lösung), Turn, Alex Martelli (erste Lösung) und der von Denis Otkidach vorgestellte Ansatz (der im Fall ohne Duplikate am schnellsten war).
Ich habe hier eine Funktion aus meiner eigenen Bibliothek eingefügt:
iteration_utilities.all_distinct
Diese kann mit der schnellsten Lösung im Fall ohne Duplikate konkurrieren und wird in konstanter Zeit für den Fall mit Duplikaten am Anfang ausgeführt (obwohl nicht so schnell).Der Code für den Benchmark:
Und für die Argumente:
quelle
Ich habe kürzlich eine verwandte Frage beantwortet , um mithilfe eines Generators alle Duplikate in einer Liste zu ermitteln. Es hat den Vorteil, dass Sie nur das erste Element abrufen müssen, wenn Sie nur feststellen möchten, ob ein Duplikat vorhanden ist, und der Rest kann ignoriert werden. Dies ist die ultimative Verknüpfung.
Dies ist ein interessanter satzbasierter Ansatz, den ich direkt von moooeeeep angepasst habe :
Dementsprechend wäre eine vollständige Liste der Dupes
list(getDupes(etc))
. Um einfach zu testen, ob ein Betrüger vorhanden ist, sollte dieser wie folgt verpackt werden:Dies lässt sich gut skalieren und bietet konsistente Betriebszeiten, wo immer sich der Betrüger in der Liste befindet - ich habe mit Listen mit bis zu 1 Mio. Einträgen getestet. Wenn Sie etwas über die Daten wissen, insbesondere darüber, dass Dupes wahrscheinlich in der ersten Hälfte auftauchen, oder über andere Dinge, mit denen Sie Ihre Anforderungen verzerren können, z. B. die Notwendigkeit, die tatsächlichen Dupes zu erhalten, gibt es einige wirklich alternative Dupe-Locators das könnte übertreffen. Die beiden, die ich empfehle, sind ...
Einfacher diktbasierter Ansatz, sehr gut lesbar:
Nutzen Sie itertools (im Wesentlichen ein ifilter / izip / tee) auf der sortierten Liste, sehr effizient, wenn Sie alle Dupes erhalten, obwohl es nicht so schnell ist, nur das erste zu erhalten:
Dies waren die Top-Performer der Ansätze, die ich für die vollständige Dupe-Liste ausprobiert habe , wobei der erste Dupe von Anfang bis Mitte irgendwo in einer 1-Meter-Elementliste vorkam. Es war überraschend, wie wenig Overhead der Sortierschritt hinzufügte. Ihr Kilometerstand kann variieren, aber hier sind meine spezifischen zeitgesteuerten Ergebnisse:
quelle
.next()
Aufruf in Ihrem zweiten Codeblock funktioniert unter Python 3.x nicht. Ich denke,next(getDupes(l))
sollte über Python-Versionen funktionieren, daher kann es sinnvoll sein, dies zu ändern.ifilter
undìzip
kann einfach durch das eingebautefilter
undzip
in Python 3.x ersetzt werden.Eine andere Möglichkeit, dies kurz und bündig zu tun, ist Counter .
So stellen Sie fest, ob die ursprüngliche Liste Duplikate enthält:
Oder um eine Liste von Elementen mit Duplikaten zu erhalten:
quelle
quelle
Ich fand, dass dies die beste Leistung erbringt, da es die Operation kurzschließt, wenn das erste Duplikat gefunden wird. Dann hat dieser Algorithmus Zeit- und Raumkomplexität O (n), wobei n die Länge der Liste ist:
quelle
Ich weiß nicht wirklich, was das Set hinter den Kulissen macht, deshalb halte ich es einfach gerne einfach.
quelle
Eine einfachere Lösung ist wie folgt. Überprüfen Sie einfach True / False mit der Pandas-
.duplicated()
Methode und nehmen Sie dann die Summe. Siehe auch pandas.Series.duplicated - pandas 0.24.1 Dokumentationquelle
Wenn die Liste nicht zerlegbare Elemente enthält, können Sie die Lösung von Alex Martelli verwenden, jedoch mit einer Liste anstelle eines Satzes, obwohl sie für größere Eingaben langsamer ist: O (N ^ 2).
quelle
Ich habe den Ansatz von pyrospade der Einfachheit halber verwendet und diesen in einer kurzen Liste aus der Windows-Registrierung ohne Berücksichtigung der Groß- und Kleinschreibung geringfügig geändert.
Wenn die unformatierte PATH-Wertzeichenfolge in einzelne Pfade aufgeteilt ist, können alle 'Null'-Pfade (leere oder nur Leerzeichen) entfernt werden, indem Folgendes verwendet wird:
Der ursprüngliche Pfad enthält zu Testzwecken sowohl Nulleinträge als auch Duplikate:
Nullpfade wurden entfernt, haben aber immer noch Duplikate, z. B. (1, 3) und (13, 20):
Und schließlich wurden die Dupes entfernt:
quelle
quelle