Wie kann ich die Duplikate in einer Python-Liste finden und eine weitere Liste der Duplikate erstellen? Die Liste enthält nur Ganzzahlen.
python
list
duplicates
MFB
quelle
quelle
Antworten:
Verwenden Sie zum Entfernen von Duplikaten
set(a)
. So drucken Sie Duplikate:Beachten Sie, dass dies
Counter
nicht besonders effizient ist ( Timings ) und hier wahrscheinlich übertrieben ist.set
wird besser abschneiden. Dieser Code berechnet eine Liste eindeutiger Elemente in der Quellreihenfolge:oder genauer:
Ich empfehle den letzteren Stil nicht, da nicht klar ist, was er
not seen.add(x)
tut (die set-add()
Methode gibt immer zurückNone
, daher ist dies erforderlichnot
).So berechnen Sie die Liste der duplizierten Elemente ohne Bibliotheken:
Wenn Listenelemente nicht hashbar sind, können Sie keine Mengen / Diktate verwenden und müssen auf eine quadratische Zeitlösung zurückgreifen (vergleichen Sie jede mit jeder). Zum Beispiel:
quelle
O(n)
, weil es die Liste nur einmal wiederholt und Set-Lookups sindO(1)
.dup = []
else: dup.append(x)
print()
seen = set()
danndupe = set(x for x in a if x in seen or seen.add(x))
quelle
l
mitset(l)
nur reduziert die Worst-Case - Zeitkomplexität und damit nicht nichts mit dieser Antwort , die größere Effizienz Bedenken auszuräumen. Es war wahrscheinlich doch nicht so einfach. Kurz gesagt, tu das nicht.Sie brauchen die Zählung nicht, nur ob der Gegenstand zuvor gesehen wurde oder nicht. Diese Antwort wurde an dieses Problem angepasst :
Nur für den Fall, dass Geschwindigkeit wichtig ist, hier einige Zeitpunkte:
Hier sind die Ergebnisse: (gut gemacht @JohnLaRooy!)
Interessanterweise ändert sich neben den Timings selbst auch das Ranking geringfügig, wenn Pypy verwendet wird. Am interessantesten ist, dass der Counter-basierte Ansatz enorm von den Optimierungen von pypy profitiert, während der von mir vorgeschlagene Methoden-Caching-Ansatz fast keine Wirkung zu haben scheint.
Anscheinend hängt dieser Effekt mit der "Duplizierung" der Eingabedaten zusammen. Ich habe
l = [random.randrange(1000000) for i in xrange(10000)]
diese Ergebnisse festgelegt und erhalten:quelle
add
jedes Mal nachschlagen (eine Wörterbuchabfrage), wenn eine Einfügung erforderlich wäre.pypy
Sie es auch, wenn Sie es zur Hand haben und Geschwindigkeit anstreben .Sie können verwenden
iteration_utilities.duplicates
:oder wenn Sie nur eines von jedem Duplikat möchten, kann dies kombiniert werden mit
iteration_utilities.unique_everseen
:Es kann auch nicht zerhackbare Elemente verarbeiten (jedoch auf Kosten der Leistung):
Das ist etwas, das nur einige der anderen Ansätze hier bewältigen können.
Benchmarks
Ich habe einen schnellen Benchmark durchgeführt, der die meisten (aber nicht alle) der hier genannten Ansätze enthält.
Der erste Benchmark umfasste nur einen kleinen Bereich von Listenlängen, da einige Ansätze dies getan haben
O(n**2)
Verhalten aufweisen.In den Diagrammen stellt die y-Achse die Zeit dar, daher bedeutet ein niedrigerer Wert besser. Es wird auch ein Protokoll-Protokoll aufgezeichnet, damit der breite Wertebereich besser visualisiert werden kann:
Entfernen der
O(n**2)
Ansätze Ich habe einen weiteren Benchmark mit bis zu einer halben Million Elementen in einer Liste durchgeführt:Wie Sie sehen können, ist der
iteration_utilities.duplicates
Ansatz schneller als jeder andere Ansatz und sogar verkettetunique_everseen(duplicates(...))
war schneller oder gleich schnell als die anderen Ansätze.Eine weitere interessante Sache, die hier zu beachten ist, ist, dass die Pandas-Ansätze für kleine Listen sehr langsam sind, aber leicht für längere Listen konkurrieren können.
Da diese Benchmarks jedoch zeigen, dass die meisten Ansätze ungefähr gleich gut abschneiden, spielt es keine Rolle, welcher verwendet wird (mit Ausnahme der 3, die
O(n**2)
Laufzeit hatten).Benchmark 1
Benchmark 2
Haftungsausschluss
1 Dies ist aus einer Drittanbieter-Bibliothek, die ich geschrieben habe :
iteration_utilities
.quelle
Ich bin auf diese Frage gestoßen, als ich mich mit etwas Ähnlichem befasst habe - und habe mich gefragt, warum niemand eine generatorbasierte Lösung angeboten hat? Die Lösung dieses Problems wäre:
Ich befasste mich mit der Skalierbarkeit und testete daher verschiedene Ansätze, einschließlich naiver Elemente, die auf kleinen Listen gut funktionieren, aber schrecklich skalieren, wenn Listen größer werden (Hinweis: Es wäre besser gewesen, timeit zu verwenden, aber dies ist illustrativ).
Ich habe @moooeeeep zum Vergleich hinzugefügt (es ist beeindruckend schnell: am schnellsten, wenn die Eingabeliste völlig zufällig ist) und einen itertools-Ansatz, der für meist sortierte Listen noch schneller ist ... Enthält jetzt den Pandas-Ansatz von @firelynx - langsam, aber nicht schrecklich und einfach. Hinweis - Der Sortier- / Abschlag- / Zip-Ansatz ist auf meinem Computer für große, meist geordnete Listen durchweg am schnellsten. Für gemischte Listen ist moooeeeep am schnellsten, aber Ihr Kilometerstand kann variieren.
Vorteile
Annahmen
Schnellste Lösung, 1m Einträge:
Ansätze getestet
Die Ergebnisse für den Test "Alle Dupes" waren konsistent und ergaben "zuerst" Duplikate, dann "alle" Duplikate in diesem Array:
Wenn die Listen zuerst gemischt werden, wird der Preis der Sortierung offensichtlich - die Effizienz sinkt merklich und der @ moooeeeep-Ansatz dominiert, wobei Set & Dict-Ansätze ähnlich sind, aber weniger Leistungsträger sind:
quelle
random.shuffle(c)
das berücksichtigen. Außerdem kann ich Ihre Ergebnisse auch beim Ausführen des unveränderten Skripts nicht replizieren (völlig andere Reihenfolge), sodass dies möglicherweise auch von der CPU abhängt.Pandas benutzen:
quelle
Sammlungen.Counter ist neu in Python 2.7:
In einer früheren Version können Sie stattdessen ein herkömmliches Diktat verwenden:
quelle
Hier ist eine saubere und prägnante Lösung -
quelle
Ohne Konvertierung in eine Liste und wahrscheinlich der einfachste Weg wäre so etwas wie unten. Dies kann während eines Interviews nützlich sein, wenn sie darum bitten, keine Sets zu verwenden
======= sonst, um 2 separate Listen mit eindeutigen Werten und doppelten Werten zu erhalten
quelle
Ich würde das mit Pandas machen, weil ich viel Pandas benutze
Gibt
Wahrscheinlich ist es nicht sehr effizient, aber es ist sicher weniger Code als viele andere Antworten, also dachte ich, ich würde dazu beitragen
quelle
pda = pd.Series(a)
print list(pda[pda.duplicated()])
Das dritte Beispiel der akzeptierten Antwort gibt eine fehlerhafte Antwort und versucht nicht, Duplikate zu geben. Hier ist die richtige Version:
quelle
Wie wäre es, wenn Sie einfach jedes Element in der Liste durchlaufen, indem Sie die Anzahl der Vorkommen überprüfen und sie dann einem Satz hinzufügen, der dann die Duplikate druckt. Hoffe das hilft jemandem da draußen.
quelle
Wir können verwenden
itertools.groupby
, um alle Gegenstände zu finden, die Dups haben:Die Ausgabe wird sein:
quelle
dupes = [x for x, y in groupby(sorted(myList)) if len(list(y)) > 1]
Ich denke, der effektivste Weg, um Duplikate in einer Liste zu finden, ist:
Es werden
Counter
alle Elemente und alle eindeutigen Elemente verwendet. Wenn Sie das erste vom zweiten subtrahieren, werden nur die Duplikate weggelassen.quelle
Ein bisschen spät, aber vielleicht hilfreich für einige. Für eine größere Liste fand ich, dass dies für mich funktionierte.
Zeigt nur und alle Duplikate und behält die Ordnung bei.
quelle
Eine sehr einfache und schnelle Möglichkeit, Dupes mit einer Iteration in Python zu finden, ist:
Die Ausgabe erfolgt wie folgt:
Dies und mehr in meinem Blog http://www.howtoprogramwithpython.com
quelle
Ich komme viel zu spät in diese Diskussion. Auch wenn ich dieses Problem gerne mit einem Liner behandeln möchte. Denn das ist der Reiz von Python. Wenn wir nur die Duplikate in eine separate Liste (oder eine beliebige Sammlung) aufnehmen möchten, würde ich Folgendes vorschlagen. Wir haben eine doppelte Liste, die wir als "Ziel" bezeichnen können.
Wenn wir nun die Duplikate erhalten möchten, können wir den einen Liner wie folgt verwenden:
Dieser Code fügt die duplizierten Datensätze als Schlüssel ein und zählt als Wert in das Wörterbuch "Duplikate". Das Wörterbuch "Duplikate" sieht wie folgt aus:
Wenn Sie nur alle Datensätze mit Duplikaten in einer Liste haben möchten, ist der Code wieder viel kürzer:
Ausgabe wird sein:
Dies funktioniert perfekt in Python 2.7.x + Versionen
quelle
Python 3.8 Einzeiler, wenn Sie keinen eigenen Algorithmus schreiben oder Bibliotheken verwenden möchten:
Druckt Artikel und Anzahl:
groupby
übernimmt eine Gruppierungsfunktion, sodass Sie Ihre Gruppierungen auf unterschiedliche Weise definieren undTuple
bei Bedarf zusätzliche Felder zurückgeben können.groupby
ist faul, also sollte es nicht zu langsam sein.quelle
Einige andere Tests. Natürlich zu tun ...
... ist zu teuer. Die nächste endgültige Methode ist ungefähr 500-mal schneller (je länger das Array, desto bessere Ergebnisse):
Nur 2 Schleifen, keine sehr kostspieligen
l.count()
Operationen.Hier ist ein Code zum Vergleichen der Methoden zum Beispiel. Der Code ist unten, hier ist die Ausgabe:
Der Testcode:
quelle
Methode 1:
Erläuterung: [val für idx, val in enumerate (input_list), wenn val in input_list [idx + 1:]] ein Listenverständnis ist, das ein Element zurückgibt, wenn dasselbe Element von seiner aktuellen Position in list, dem Index, vorhanden ist .
Beispiel: input_list = [42,31,42,31,3,31,31,5,6,6,6,6,6,7,42]
Beginnend mit dem ersten Element in der Liste 42 mit dem Index 0 wird geprüft, ob das Element 42 in der Eingabeliste [1:] vorhanden ist (dh von Index 1 bis zum Ende der Liste), da 42 in der Eingabeliste [1:] vorhanden ist. wird es 42 zurückgeben.
Dann geht es zum nächsten Element 31 mit Index 1 und prüft, ob Element 31 in der Eingabeliste [2:] vorhanden ist (dh von Index 2 bis zum Ende der Liste), da 31 in Eingabeliste [2:] vorhanden ist. es wird 31 zurückgeben.
In ähnlicher Weise werden alle Elemente in der Liste durchlaufen und nur die wiederholten / doppelten Elemente in eine Liste zurückgegeben.
Da wir dann Duplikate in einer Liste haben, müssen wir eines von jedem Duplikat auswählen, dh Duplikate unter Duplikaten entfernen. Dazu rufen wir ein in Python eingebautes namens set () auf und es entfernt die Duplikate.
Dann bleibt uns eine Menge übrig, aber keine Liste. Um von einer Menge in eine Liste zu konvertieren, verwenden wir typecasting, list () und konvertieren die Menge der Elemente in eine Liste.
Methode 2:
Erläuterung: Hier erstellen wir zunächst zwei leere Listen. Durchlaufen Sie dann alle Elemente der Liste, um festzustellen, ob sie in temp_list vorhanden sind (anfangs leer). Wenn es nicht in der temp_list vorhanden ist, fügen wir es mithilfe der append- Methode zur temp_list hinzu .
Wenn es bereits in temp_list vorhanden ist, bedeutet dies, dass das aktuelle Element der Liste ein Duplikat ist. Daher müssen wir es mit der Methode append zu dupe_list hinzufügen .
quelle
Sie entfernen Duplikate im Grunde genommen, indem Sie sie in set (
clean_list
) konvertieren und dann die iterierenraw_list
, während Sie jedesitem
in der Bereinigungsliste für das Auftreten in entfernenraw_list
. Wird diesitem
nicht gefunden, wird die ausgelösteValueError
Ausnahme abgefangen unditem
zurduplicated_items
Liste hinzugefügt .Wenn der Index der duplizierten Elemente benötigt wird, nur
enumerate
die Liste und spielen Sie mit dem Index herum. (for index, item in enumerate(raw_list):
) ist schneller und optimiert für große Listen (wie Tausende von Elementen)quelle
Verwendung der
list.count()
Methode in der Liste, um die doppelten Elemente einer bestimmten Liste herauszufindenquelle
Einzeiler, zum Spaß und wenn eine einzige Aussage erforderlich ist.
quelle
quelle
Einzeilige Lösung:
quelle
Hier oben gibt es viele Antworten, aber ich denke, dies ist ein relativ gut lesbarer und leicht verständlicher Ansatz:
Anmerkungen:
quelle
Hier ist ein schneller Generator, der ein Diktat verwendet, um jedes Element als Schlüssel mit einem booleschen Wert zu speichern, um zu überprüfen, ob das doppelte Element bereits ausgegeben wurde.
Für Listen mit allen Elementen, die Hash-Typen sind:
Für Listen, die möglicherweise Listen enthalten:
quelle
quelle
Bei Verwendung von toolz :
quelle
So musste ich es machen, weil ich mich herausforderte, keine anderen Methoden anzuwenden:
Ihre Probe funktioniert also wie folgt:
quelle
duplist = list(set(a))
.