Wie entfernen Sie Dubletten aus einer Liste, während Sie die Reihenfolge beibehalten?
Gibt es eine integrierte, entfernt Duplikate aus der Liste in Python, bei gleichzeitiger Wahrung von Ordnung? Ich weiß, dass ich verwenden können, eine Reihe Duplikate entfernen, aber das zerstört den ursprünglichen Auftrag. Ich weiß auch, dass ich Rollen kann meine eigene wie diese:
def uniq(input):
output = []
for x in input:
if x not in output:
output.append(x)
return output
(Dank entspannen für das Codebeispiel.)
Aber ich würde gerne Erlaube mir, ein built-in oder ein mehr Pythonic idiom, wenn möglich.
InformationsquelleAutor der Frage Josh Glover | 2009-01-26
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier haben Sie einige alternativen: http://www.peterbe.com/plog/uniqifiers-benchmark
Schnellste:
Warum weisen Sie
seen.add
zuseen_add
statt nur mitzugehenseen.add
? Python ist eine dynamische Sprache, und die Lösungseen.add
jeder iteration ist teurer als die Lösung eines lokalen Variablen.seen.add
geändert haben könnten, zwischen den Iterationen und die Laufzeit ist nicht smart genug, um ausschließen. Es sicher zu spielen, es ist zu prüfen, das Objekt jedes mal.Wenn Sie planen, mit dieser Funktion eine Menge auf dem gleichen dataset, vielleicht würdest du besser mit einem sortierten Satz: http://code.activestate.com/recipes/528878/
O(1) Einfügung, - Löschung und-Mitglied-check pro Betrieb.
InformationsquelleAutor der Antwort Markus Jarderot
Bearbeiten 2016
Raymond hingewiesenin python 3.5+, wo
OrderedDict
ist implementiert in C, die Liste Verständnis Ansatz wird langsamer sein alsOrderedDict
(es sei denn, Sie wirklich brauchen, die Liste am Ende - und auch nur dann, wenn der Eingang ist sehr kurz). Also ist die beste Lösung für 3.5+ istOrderedDict
.Wichtig, Bearbeiten, 2015
Als @abarnert Noten, die
more_itertools
Bibliothek (pip install more_itertools
) enthält eineunique_everseen
Funktion, die integriert ist, dieses problem zu lösen, ohne unlesbar (not seen.add
) Mutationen in der Liste Verstehens. Dies ist auch die Schnellste Lösung zu:Nur eine einfache Bibliothek importieren und keine hacks.
Dies kommt von einer Umsetzung der itertools Rezept
unique_everseen
, die wie folgt aussieht:In Python
2.7+
akzeptiert gängige idiom(das geht aber nicht auf Geschwindigkeit optimiert ist, würde ich jetzt verwendenunique_everseen
) für diese verwendetSammlungen.OrderedDict
:Laufzeit: O(N)
Das sieht viel schöner aus als:
und nutzen nicht die hässlicher hack,:
die stützt sich auf die Tatsache, dass
set.add
ist ein in-place-Methode, die immer wiederNone
sonot None
ausgewertetTrue
.Beachten Sie jedoch, dass die hack-Lösung ist schneller im raw-Geschwindigkeit, obwohl es hat die gleiche Laufzeit Komplexität von O(N).
InformationsquelleAutor der Antwort
In Python 2.7die neue Art, das entfernen von Duplikaten aus einer iterierbar, während es in der original-Reihenfolge ist:
In Python 3.5die OrderedDict hat eine C-Implementierung. Meine timings zu zeigen, dass diese jetzt sowohl die Schnellste und kürzeste der verschiedenen Ansätze für Python 3.5.
In Python 3.6die regelmäßige dict wurde beide bestellt und kompakt. (Diese Funktion gilt für CPython und PyPy kann aber nicht in anderen Implementierungen). Das gibt uns eine neue Schnellste Weg, deduping unter Beibehaltung der Reihenfolge:
In Python 3.7die regelmäßige dict garantiert beide bestellt in allen Implementierungen. So, die kürzeste und Schnellste Lösung ist:
Antwort auf @max: Sobald Sie sich bewegen, 3.6 oder 3.7 und Verwendung der regulären dict statt OrderedDictman kann wirklich nicht schlagen die Leistung in sonstiger Weise. Das Wörterbuch ist dicht und leicht, in eine Liste konvertiert mit fast keinen overhead. Die Ziel-Liste ist die vor-size-len(d), welches alle die Größe, die auftreten, in einer Liste erfassen. Auch, da der interne Schlüssel-Liste ist dicht, kopieren Sie den Zeiger über fast schneller, als eine Liste zu kopieren.
InformationsquelleAutor der Antwort Raymond Hettinger
einzigartigen →
['1', '2', '3', '6', '4', '5']
InformationsquelleAutor der Antwort dansalmo
Der Liste nicht einmal sortiertdie hinreichende Bedingung ist, dass gleiche Werte zusammengefasst sind.
Edit: bin davon ausgegangen, dass die "Erhaltung der Ordnung" bedeutet, dass die Liste tatsächlich bestellt. Wenn dies nicht der Fall ist, dann ist die Lösung von MizardX ist der richtige.
Gemeinschaft edit: Das ist jedoch der eleganteste Weg, um "komprimieren aufeinander folgende Elemente in einem einzigen element".
InformationsquelleAutor der Antwort Rafał Dowgird
Ich denke wenn Sie möchte erhalten den Auftrag,
Sie können versuchen, diese:
ODER ähnlich können Sie dies tun:
Sie können dies auch tun:
Es kann auch geschrieben werden als:
InformationsquelleAutor der Antwort shamrock
Für eine weitere, sehr späte Antwort zu einem anderen sehr alten Frage:
Den
itertools
Rezepte haben eine Funktion, die dies tut, mit derseen
set Technik, aber:key
Funktion.seen.add
anstatt es bis N-mal. (f7
tut dies auch, aber einige Versionen nicht.)ifilterfalse
so müssen Sie nur die Schleife über die einzigartigen Elemente in Python, anstelle von alle von Ihnen. (Sie immer noch iterieren über alle von Ihnen innerhalbifilterfalse
natürlich, aber das ist in C, und viel schneller.)Ist es tatsächlich schneller als
f7
? Es hängt von Ihren Daten, so dass Sie ll haben, um es zu testen und zu sehen. Wenn Sie möchten, eine Liste am Endef7
verwendet eine listcomp, und es gibt keine Möglichkeit, das zu tun hier. (Sie können sich direktappend
stattyield
ing, oder Sie können den feed generator in derlist
Funktion, aber keiner kann so schnell sein, wie die LIST_APPEND innerhalb einer listcomp.) Jedenfalls, in der Regel, drückte ein paar Mikrosekunden ist nicht so wichtig wie ein leicht-verständlich -, wiederverwendbare -, schon-geschrieben-Funktion nicht erforderlich ist, DSU, wenn Sie wollen zu dekorieren.Als mit all den Rezepten, es ist auch verfügbar in
mehr-iterools
.Wenn Sie wollen einfach nur die no-
key
Fall, man kann es vereinfachen:InformationsquelleAutor der Antwort abarnert
Nur um ein weiteres (sehr performant) die Umsetzung einer solchen Funktionalität von einem externen Modul1:
iteration_utilities.unique_everseen
:Timings
Habe ich einige timings (Python 3.6), und diese zeigen, dass es schneller als alle anderen alternativen, die ich getestet, einschließlich
OrderedDict.fromkeys
f7
undmore_itertools.unique_everseen
:Und nur um sicherzugehen, ich habe auch einen test mit mehr Duplikate nur um zu überprüfen, ob es einen Unterschied macht:
Und enthält nur einen Wert:
In allen diesen Fällen ist die
iteration_utilities.unique_everseen
- Funktion ist die Schnellste (auf meinem computer).Diese
iteration_utilities.unique_everseen
Funktion kann auch mit unhashable Werte in der input - (aber mit einemO(n*n)
Leistung anstelle derO(n)
Leistung, wenn die Werte hashable).1 Disclaimer: ich bin der Autor des Pakets.
InformationsquelleAutor der Antwort MSeifert
Für keine hashable Arten (z.B. Liste von Listen), basierend auf MizardX:
InformationsquelleAutor der Antwort zmk
Nicht zum kicken ein Totes Pferd (diese Frage ist sehr alt und hat schon viele gute Antworten), aber hier ist die Lösung mit den pandas, die sehr schnell in viele Umstände und ist tot einfach zu bedienen.
InformationsquelleAutor der Antwort Alexander
Kreditaufnahme die rekursive Idee verwendet in definining Haskell ist
nub
- Funktion für Listen, dies wäre ein rekursiver Ansatz:z.B.:
Ich habe versucht, es für den Anbau von Daten, Größen und sah sub-linearer Zeit-Komplexität (nicht endgültig, schlägt aber vor, diese sollten in Ordnung sein, für normale Daten).
Ich denke auch, es ist interessant, dass dies könnte werden leicht verallgemeinert, um die Einzigartigkeit von anderen Operationen. Wie diese:
Beispielsweise könnten Sie eine Funktion, die verwendet den Begriff der Rundung die gleiche ganze Zahl, als ob es war, "die Gleichheit" für die Einzigartigkeit Zwecke, wie folgt:
dann eindeutig(some_list, test_round) würde die einzigartigen Elemente der Liste, wo die Eindeutigkeit nicht mehr gedacht traditionelle Geschlechter (die implizit durch die Verwendung von jeglicher Art von set-based oder dict-key-basierten Ansatz, um dieses problem, sondern soll nur das erste element, die Runden zu K für jede mögliche ganze Zahl K, die die Elemente können in Runden, z.B.:
InformationsquelleAutor der Antwort ely
5 x schneller reduzieren Variante aber anspruchsvoller
Erklärung:
InformationsquelleAutor der Antwort Sergey M Nikitin
Können Sie auf eine Liste Verständnis, wie es gebaut wird durch das symbol '_[1]'.
Zum Beispiel die folgende Funktion einzigartig-ifies eine Liste der Elemente ohne änderung Ihrer Bestellung durch den Verweis auf die Liste Verständnis.
Demo:
Ausgabe:
InformationsquelleAutor der Antwort Zhifeng Hu
MizardX die Antwort gibt eine gute Sammlung mehrerer Ansätze.
Dies ist, was ich kam mit, während Sie laut denken:
InformationsquelleAutor der Antwort Saurabh Hirani
Könnten Sie tun, eine Art hässliche Liste Verständnis hack.
InformationsquelleAutor der Antwort
Relativ wirksam Ansatz mit
_sorted_
einenumpy
arrays:Ausgänge:
InformationsquelleAutor der Antwort dominecf
Einen generator-Ausdruck, der verwendet wird O(1) suchen einer Gruppe, um festzustellen, ob oder nicht, um ein element in die neue Liste.
InformationsquelleAutor der Antwort kiley.a
Eine einfache rekursive Lösung:
InformationsquelleAutor der Antwort Ilya Prokin
In Python 3.7 und oben, Wörterbücher garantiert zu erinnern, Ihre Schlüssel einsetzen, um. Die Antwort auf diese Frage fasst den aktuellen Stand der Dinge.
Den
OrderedDict
Lösung wird damit obsolet und ohne import-Anweisungen können wir einfach die Frage:InformationsquelleAutor der Antwort timgeb
Wenn du eine brauchst, liner, dann wird das vielleicht helfen:
... sollte funktionieren, aber korrigieren Sie mich, wenn ich falsch bin,
InformationsquelleAutor der Antwort code22
Wenn Sie routinemäßig
pandas
und ästhetik den Vorzug gegenüber der Leistung, dann erwägen, die built-in Funktionpandas.Series.drop_duplicates
:Timing:
InformationsquelleAutor der Antwort Lei
das bewahrt Ordnung und laufen in O(n) Zeit. im Grunde die Idee ist, erstellen Sie ein Loch, wo es ist ein Duplikat gefunden und Spüle es hinunter auf den Grund. macht Gebrauch von einer lese-und schreib-Zeiger. wenn ein Duplikat gefunden wird, nur die lese-Zeiger Fortschritte und schreiben Zeiger bleibt auf den doppelten Eintrag zu überschreiben.
InformationsquelleAutor der Antwort Soham Joshi
Eine Lösung ohne Verwendung der importierten Module oder sets:
Gibt Ausgabe:
InformationsquelleAutor der Antwort Rob Murray
Da ich auf der Suche an einem dup und sammelte einige Verwandte, aber unterschiedliche, Bezug, nützliche, Informationen, die nicht Teil der anderen Antworten, hier sind zwei andere mögliche Lösungen.
.bekommen(Wahr) XOR .setdefault(False)
Die erste ist sehr ähnlich wie das angenommen
seen_add
soultion nutzen, aber mit expliziten Nebenwirkungen mit Wörterbuchget(x,<default>)
undsetdefault(x,<default>)
:get(x,<default>)
zurück<default>
wennx
ist nicht im Wörterbuch, aber nicht fügen Sie den Schlüssel in das Wörterbuch.set(x,<default>)
gibt den Wert zurück, falls der Schlüssel im dictionary, sonst setzt es an und zurück<default>
.Beiseite:
a != b
ist, wie man ein XOR in python__ÜBERWIEGENDES ___fehlen_____ (inspiriert durch diese Antwort)
Die zweite Technik ist das überschreiben der
__missing__
Methode, die aufgerufen wird, wenn der Schlüssel existiert nicht in einem Wörterbuch, das nur aufgerufen, wenn mitd[k]
notation:Vom die docs:
InformationsquelleAutor der Antwort cod3monk3y
Hier ist meine 2 Cent dazu:
Grüße,
Yuriy
InformationsquelleAutor der Antwort Yuriy Samorodov
dies ist die smartes Weg, um entfernen Sie Duplikate aus einer Liste in Python, während die Erhaltung seiner Ordnung, können Sie sogar tun Sie es in einer Zeile code:
InformationsquelleAutor der Antwort Liam
Mein Kumpel Wes hat mir dieses süße Antwort mit Liste Verstehens.
Beispiel-Code:
InformationsquelleAutor der Antwort corax
Nur hinzufügen, eine andere Antwort habe ich nicht gesehen, aufgeführt
Dies ist mit
.index
zu bekommen, der erste index, der jedem element in der Liste und loszuwerden doppelte Ergebnisse (für die sich wiederholenden Elemente), mitset
dann Sortieren, weil es gibt keine Reihenfolge, in der Sätze. Beachten Sie, dass wir nicht Locker, um Informationen, weil der erste index, der jedes neue element wird immer in aufsteigender Reihenfolge. So sortiert wird immer richtig stellen.Habe ich nur als der einfache syntax, nicht die Leistung.
InformationsquelleAutor der Antwort progmatico