Hallo zusammen,
ich habe eine kurze Frage. Und zwar will ich aus einer Liste doppelte Elemente entfernen. Das geht ja beispielsweise mit set(). Nur habe ich das Problem, dass dies meine Reihenfolge ändert. Da ich das nicht möchte bin ich auf der Suche nach einer anderen Möglichkeit. Kann mir da jemand helfen?
Wär super!
Danke!
Doppelte Elemente entfernen ohne Reihenfolge zu ändern
-
- User
- Beiträge: 28
- Registriert: Dienstag 16. April 2013, 12:40
Hey mickimick,
du kannst für eine Liste
verwenden. Das gibt dir dann das gewünschte Ergebnis
du kannst für eine Liste
- L=[1,2,3,3,4,4,5,6]
Code: Alles auswählen
sorted(list(set(L))
- L=[1,2,3,4,5,6]
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
So könnte man es machen:
@mathematik: Deine Lösung setzt voraus, dass die Ursprungsliste sortiert vorliegt!
Code: Alles auswählen
source = [7, 1, 2, 6, 1, 3, 2, 1, 6, 5, 3]
result = []
found = set()
for item in source:
if item not in found:
found.add(item)
result.append(item)
result
> [7, 1, 2, 6, 3, 5]
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
oder mit Hilfe von collections:
Code: Alles auswählen
from collections import OrderedDict
result = OrderedDict(zip(source,source)).keys()
@jerch: in diese Falle tappt man auch als fortgeschrittener Forumsteilnehmer immer mal wieder.
Hier natürlich die "richtige" Lösung, die nach der mittleren Position der Elemente sortiert:
Hier natürlich die "richtige" Lösung, die nach der mittleren Position der Elemente sortiert:

Code: Alles auswählen
def iindex(elements, value):
try:
k=0
while True:
k=elements.index(value, k+1)
yield k
except ValueError:
pass
result = [x for _pos,x in sorted((sum(iindex(source, x))/float(source.count(x)), x) for x in set(source))]
- pillmuncher
- User
- Beiträge: 1527
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Code: Alles auswählen
def uniquify_keep_first_found(iterable):
seen = set()
seen_add = seen.add
return (
each for each in iterable if each not in seen and not seen_add(each))
def uniquify_keep_last_found(iterable):
from operator import itemgetter
get_second = itemgetter(1)
last_seen = {}
for i, each in enumerate(iterable):
last_seen[each] = i
return (each for each, _ in sorted(last_seen.items(), key=get_second))
print(list(uniquify_keep_first_found([1, 2, 3, 4, 3, 4, 3, 6, 2, 8, 9, 8])))
print(list(uniquify_keep_last_found([1, 2, 3, 4, 3, 4, 3, 6, 2, 8, 9, 8])))
Code: Alles auswählen
$ python uniqui.py
[1, 2, 3, 4, 6, 8, 9]
[1, 4, 3, 6, 2, 9, 8]
In specifications, Murphy's Law supersedes Ohm's.
@pillmuncher Ich finde es fragwürdig, Generatorausdrücke mit Seiteneffekten zu schreiben, und der kleine Trick mit "and", der sich noch dazu auf den undokumentierten Rückgabewert von "set.add()" verlässt, macht es nicht besser.
Mag sein, dass Du das anders siehst, doch ich finde diese Lösung weder elegant noch schön noch cool(TM), sondern schlicht fahrlässig.
Mag sein, dass Du das anders siehst, doch ich finde diese Lösung weder elegant noch schön noch cool(TM), sondern schlicht fahrlässig.
- pillmuncher
- User
- Beiträge: 1527
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@lunar: Vielleicht gefällt dir ja das hier besser:
Code: Alles auswählen
def uniquify_keep_first_found(iterable):
seen = {}
seen_setdefault = seen.setdefault
return (seen_setdefault(e,e) for e in iterable if e not in seen)
In specifications, Murphy's Law supersedes Ohm's.
Was wohl hier die gesuchte Reihenfolge ist: 
Code: Alles auswählen
[0,0,2,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,1,2,0,0,0,1,0,2,0,2,0,0,0,0,1,0,0,0,2,0,0,0,0]

@jerch:
Code: Alles auswählen
[0, 2, 1]
Das Leben ist wie ein Tennisball.
@EyDu: Ich wollte damit auf die Verteilung hinaus, wenn man das mal plottet, kommt man eher auf [0,1,2]. Das Beispiel sollte eigentlich nur zeigen, dass es viele Kriterien der "Reihenfolge" gibt (von ntem Vorkommen über Mittelwerte bis komplexe Verteilungsmodelle) und ohne weitere Angaben da nur Rätselraten angesagt ist.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Also im Kontext einer Python-Liste ist das Wort Reihenfolge imho eindeutig belegt, nämlich durch die Reihenfolge der Listenelemente! Ich finde in diesem Falle müsste man ganz im Gegenteil explizit benennen, dass man eine andere Reihenfolge meint.
Darüber hinaus fügt der OP zusätzlich an, dass ``set`` die "Reihenfolge" durcheinander bringt - was ein weiteres Indiz dafür ist, dass der OP die Reihenfolge der Elemente meint.
Unglücklich an seiner Formulierung ist lediglich das "meine" - erst dadurch könnte man verleitet werden zu glauben, es handele sich um eine spezielle Reihenfolge. Vermutlich ist das aber eher eine Schwäche in der Diktion
@snafu: Tja, da kann man nix machen
Darüber hinaus fügt der OP zusätzlich an, dass ``set`` die "Reihenfolge" durcheinander bringt - was ein weiteres Indiz dafür ist, dass der OP die Reihenfolge der Elemente meint.
Unglücklich an seiner Formulierung ist lediglich das "meine" - erst dadurch könnte man verleitet werden zu glauben, es handele sich um eine spezielle Reihenfolge. Vermutlich ist das aber eher eine Schwäche in der Diktion

@snafu: Tja, da kann man nix machen

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Seh ich auch so. Nur ist die "Reduktion" eben nicht definiert. Wen ich mit einem WürfelHyperion hat geschrieben:Also im Kontext einer Python-Liste ist das Wort Reihenfolge imho eindeutig belegt, nämlich durch die Reihenfolge der Listenelemente!
Code: Alles auswählen
2,6,3,6
@pillmuncher Nun, auch dieser Generatorausdruck hat immer noch einen Seiteneffekt, nicht wahr? Ich fände eine for-Schleife mit "yield" besser...
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Stand doch gleich im ersten Posting:jerch hat geschrieben:Nur ist die "Reduktion" eben nicht definiert.
mickimick hat geschrieben:Und zwar will ich aus einer Liste doppelte Elemente entfernen.

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@Hyperion:
Liest Du in die Aussage nicht ein bisschen viel rein?
Ok doppelte Elemente entfernen: 
Liest Du in die Aussage nicht ein bisschen viel rein?
Ok doppelte Elemente entfernen:
Code: Alles auswählen
[1,2,3,2,3,3]-->[1,3,3,3]

- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Also ehrlich gesagt legst Du zu viel Präzision in die Frage des OPjerch hat geschrieben:@Hyperion:
Liest Du in die Aussage nicht ein bisschen viel rein?
Ok doppelte Elemente entfernen:Code: Alles auswählen
[1,2,3,2,3,3]-->[1,3,3,3]

Jaja, von dreifach vorkommenden schreibt er ja auch nichts...

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert