Wie würdet ihr die Elemente einer Liste, die doppelt vorkommen, entfernen?
Nein, ich meine nicht die Reduktion auf je ein Exemplar pro Element (also z.B. über Umwandlung in ein set), sondern die vollständige Entfernung dieser Elemente, so dass nur noch die Elemente übrigbleiben, die einmalig waren.
Konkret handelt es sich bei den Listenelementen um Tupel mit Zahlenwerten.
Meine erste Lösung sieht so aus, dass ich ein set der Liste anfertige, dieses durchlaufe und prüfe, ob die Anzahl der einzelnen Elemente in der Liste größer als 1 ist. Wenn ja, werden sie aus der Liste entfernt. Funktional einwandfrei.
ABER: Ist nicht elegant. Wie kann man das schöner lösen? (Performance ist nicht das Problem. Die Liste ist nicht lang.)
Doppelte Elemente einer Liste elegant entfernen
Ungetestet:
Erhält sogar die Reihenfolge der Werte aus `list_a`.
Code: Alles auswählen
histogram = defaultdict(int)
for item in list_a:
histogram[item] += 1
result = [x for x in list_a if histogram[x] == 1]
Jop, schließe mich BlackJack an; ``collections.defaultdict`` war mein erster Gedanke.
Alternativ vielleicht von ``set`` (oder gleich ``list``) so ableiten, dass ``add()`` (bzw. ``__setitem__()``[?]) bei der Anweisung, ein bereits vorhandenes Element hinzuzufügen, dieses direkt löscht und das übergebene Element verwirft. Je nachdem, in welchem Umfang du das nutzen willst.
Alternativ vielleicht von ``set`` (oder gleich ``list``) so ableiten, dass ``add()`` (bzw. ``__setitem__()``[?]) bei der Anweisung, ein bereits vorhandenes Element hinzuzufügen, dieses direkt löscht und das übergebene Element verwirft. Je nachdem, in welchem Umfang du das nutzen willst.
Dann benötigt man aber ein "set" im "set", um die Liste der bereits verworfenen Elemente zu speichern. Ansonsten führt nämlich der dritte "set.add()" Aufruf dazu, dass das Element wieder hinzugefügt wird.Y0Gi hat geschrieben:Alternativ vielleicht von ``set`` (oder gleich ``list``) so ableiten, dass ``add()`` (bzw. ``__setitem__()``[?]) bei der Anweisung, ein bereits vorhandenes Element hinzuzufügen, dieses direkt löscht und das übergebene Element verwirft. Je nachdem, in welchem Umfang du das nutzen willst.
Vielen Dank für eure Vorschläge. Die Idee mit dem dictionary ist interessant.
Die Ausführungen von Y0Gi haben noch eine andere Erleuchtung mit sich gebracht: Da die besagte Liste zuvor vom Programm selbst erzeugt wird, und zwar sukzessive via append, ist es natürlich am schlauesten, ein schon vorhandenes Element gar nicht erst erneut anzuhängen, sondern das schon vorhandene stattdessen zu löschen ...
Die Ausführungen von Y0Gi haben noch eine andere Erleuchtung mit sich gebracht: Da die besagte Liste zuvor vom Programm selbst erzeugt wird, und zwar sukzessive via append, ist es natürlich am schlauesten, ein schon vorhandenes Element gar nicht erst erneut anzuhängen, sondern das schon vorhandene stattdessen zu löschen ...
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
User + Posting gelöscht, aber durch das Zitat ist der Spam immer noch da...
Edit: Danke fürs ausbessern, numerix.
Was ich mich ja frage, warum zitiert man denn Spam?numerix hat geschrieben:
Edit: Danke fürs ausbessern, numerix.
Zuletzt geändert von Leonidas am Donnerstag 29. Januar 2009, 17:57, insgesamt 1-mal geändert.
Hier meine Lösung:
Aber ich denke, es ist Jacke wie Hose. BlackJacks ist auch nicht schlecht.
Code: Alles auswählen
a = [3,4,3,5,3,2,2,1]
print [i for i in set(a) if a.count(i)<2]
Das set brauchts in dem Code von hendrikS nich.
So bleibt auch die Reihenfolge gewahrt.
Find ich persönlich viel eleganter als die defaultdict Variante.
EDIT: @HWK: Ich denk auf Zeit kommts nicht an?
Code: Alles auswählen
>>> a = [3,4,3,5,3,2,2,1]
>>> [i for i in a if a.count(i)<2]
[4, 5, 1]
Find ich persönlich viel eleganter als die defaultdict Variante.
EDIT: @HWK: Ich denk auf Zeit kommts nicht an?
Zuletzt geändert von HerrHagen am Donnerstag 29. Januar 2009, 17:56, insgesamt 1-mal geändert.
Ich dachte tatsächlich, der hätte sich was dabei gedacht ...Leonidas hat geschrieben:User + Posting gelöscht, aber durch das Zitat ist der Spam immer noch da...Was ich mich ja frage, warum zitiert man denn Spam?numerix hat geschrieben:
Im übrigen war das ursprüngliche Problem in diesem Thread schon gelöst ...
Das mag stimmen, aber premature optimisation is the root of all evil und so. Ich hab jüngst erst festgestellt, dass einer meiner algorithmen durchs (ineffiziente) stringaneinanderkleben gar nicht so sehr verlangsamt wurde wie durch meine Optimierungsansätze.HWK hat geschrieben:@hendrikS: Deins ist zwar weniger Quellcode, dürfte bei langen Listen aber deutlich länger brauchen, da count() die Liste ja jedesmal neu durchlaufen muss.
Ich fände es gut, wenn ein Problem gelöst ist, es auch als solches zu markieren. Hat mich nicht viel Zeit gekostet.numerix hat geschrieben: Im übrigen war das ursprüngliche Problem in diesem Thread schon gelöst ...
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ich fände es schlecht und das wurde auch schon mehrfach diskutiert. Die Nachteile des "gelöst" markierens überwiegen.hendrikS hat geschrieben:Ich fände es gut, wenn ein Problem gelöst ist, es auch als solches zu markieren. Hat mich nicht viel Zeit gekostet.