Ich verwende häufig sorted
und groupby
, um doppelte Elemente in einem iterablen Objekt zu finden. Jetzt sehe ich, dass es unzuverlässig ist:
Der Grund, warum der obige Code in Python 2.x fehlschlägt, ist hier erklärt .
Was ist eine zuverlässige pythonische Methode, um Duplikate zu finden?
Ich habe nach ähnlichen Fragen / Antworten zu SO gesucht. Das beste von ihnen ist " Wie nehme ich in Python eine Liste und reduziere sie auf eine Liste von Duplikaten? ", aber die akzeptierte Lösung ist nicht pythonisch (es ist prozedurale Multilinie für ... wenn ... add ... else ... add ... return result) und andere Lösungen sind unzuverlässig (hängt von der nicht erfüllten Transitivität des Operators "& lt;" ab) oder sind langsam (O n * n).
[BEARBEITEN] Geschlossen. Die angenommene Antwort hat mir geholfen, Schlussfolgerungen in meiner Antwort unten allgemeiner zusammenzufassen.
Ich verwende gerne eingebaute Typen, um z.B. Baumstrukturen. Deshalb habe ich jetzt Angst vor der Mischung.
Fazit:
groupby(sorted(..))
unter Bedingungen sehr gut
Counter(map(pickled.dumps, data))
anstelle von Counter(data)
und entpacke es schließlich oder groupby(sorted(data, key=pickled.dumps))
wenn das unpickling unerwünscht ist oder kein Python 2.7 Alle anderen Lösungen in anderen Fragen sind derzeit schlechter .
Anmerkungen:
Ich dachte darüber nach, Artikel nach Typ vorzusortieren oder sie durch Hash für hashable Elemente zu erweitern, es hilft derzeit, aber es ist keine sichere Lösung, weil das gleiche Problem mit "& lt;" Operator Insite Listen, Tupel etc.
Dieses Thema ist für mich interessant, also habe ich die obige Lösung gegen die im anderen Thread akzeptierte Lösung zeitlich abgestimmt.
Die Counter-Methode ist dieser Thread ist sehr elegant; akzeptierte Antwort in diesem Thread Wie nehme ich in Python eine Liste und reduziere sie auf eine Liste von Duplikaten? scheint etwa 2 mal schneller zu sein.
%Vor%Ergebnisse:
%Vor%Ich habe das unter verschiedenen Spezifikationen versucht und das Ergebnis immer das selbe.
Allerdings gibt es in beiden Lösungen eine Falle. Der Grund dafür ist, dass die Werte mit demselben Hashwert zusammengeführt werden. Es kommt also darauf an, ob die verwendeten Werte den gleichen Hashwert haben. Es ist nicht dieser verrückte Kommentar, wie Sie vielleicht denken (ich war auch früher überrascht), weil Python einige Werte auf die besondere Art und Weise hasht. Probieren Sie:
%Vor%Die 1, 1.0 und True haben per Definition den gleichen Hash und ähnlich die 0, 0.0 und False. Es druckt Folgendes auf meiner Konsole (denke an die letzten beiden Zeilen - alle Werte sollten eigentlich Duplikate sein):
%Vor% Nur weil ich neugierig war, hier ist die Lösung, die einen Unterschied zwischen 0, False, 0.0 usw. macht. Es basiert auf dem Sortieren der Sequenz mit my_cmp
, die auch den Typ des Gegenstandes berücksichtigt. Es ist natürlich sehr langsam im Vergleich zu den oben genannten Lösungen. Dies liegt an der Sortierung. Aber vergleichen Sie die Ergebnisse!
Es druckt auf meiner Konsole:
%Vor%Tags und Links python sorting python-2.x