Seite 1 von 1

Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Montag 9. September 2013, 19:42
von mickimick
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!

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Montag 9. September 2013, 19:49
von mathematik
Hey mickimick,

du kannst für eine Liste
  • L=[1,2,3,3,4,4,5,6]

Code: Alles auswählen

sorted(list(set(L))
verwenden. Das gibt dir dann das gewünschte Ergebnis
  • L=[1,2,3,4,5,6]

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Montag 9. September 2013, 19:55
von Hyperion
So könnte man es machen:

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]
@mathematik: Deine Lösung setzt voraus, dass die Ursprungsliste sortiert vorliegt!

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Montag 9. September 2013, 20:57
von Sirius3
oder mit Hilfe von collections:

Code: Alles auswählen

from collections import OrderedDict
result = OrderedDict(zip(source,source)).keys()

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Montag 9. September 2013, 22:55
von jerch
@mickimick:
Deine Frage ist nicht klar - Was ist denn die gewünschte Reihenfolge? Welches Vorkommen von x bestimmt diese? Die hier gezeigten Varianten gehen davon aus, dass das erste Vorkommen die Reihenfolge bestimmt.

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 06:19
von Sirius3
@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: :wink:

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))]

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 18:29
von pillmuncher

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])))
Ergebnis:

Code: Alles auswählen

$ python uniqui.py
[1, 2, 3, 4, 6, 8, 9]
[1, 4, 3, 6, 2, 9, 8]

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 19:36
von lunar
@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.

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 22:06
von pillmuncher
@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)

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 22:45
von jerch
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]
:twisted:

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Dienstag 10. September 2013, 23:17
von EyDu
@jerch:

Code: Alles auswählen

[0, 2, 1]

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 08:12
von snafu
Immer wieder schön, wenn Threadersteller nach ihrer Frage nichts mehr von sich hören lassen. :)

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 11:13
von jerch
@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.

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 12:09
von Hyperion
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 ;-)

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 18:24
von jerch
Hyperion hat geschrieben:Also im Kontext einer Python-Liste ist das Wort Reihenfolge imho eindeutig belegt, nämlich durch die Reihenfolge der Listenelemente!
Seh ich auch so. Nur ist die "Reduktion" eben nicht definiert. Wen ich mit einem Würfel

Code: Alles auswählen

2,6,3,6
würfle, ist eben das die Reihenfolge, wie will man das reduzieren, ohne die "Reduktionsregeln" zu kennen? Danach habe ich gefragt.

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 18:30
von lunar
@pillmuncher Nun, auch dieser Generatorausdruck hat immer noch einen Seiteneffekt, nicht wahr? Ich fände eine for-Schleife mit "yield" besser...

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 19:31
von Hyperion
jerch hat geschrieben:Nur ist die "Reduktion" eben nicht definiert.
Stand doch gleich im ersten Posting:
mickimick hat geschrieben:Und zwar will ich aus einer Liste doppelte Elemente entfernen.
;-)

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 20:33
von jerch
@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]
:twisted:

Re: Doppelte Elemente entfernen ohne Reihenfolge zu ändern

Verfasst: Mittwoch 11. September 2013, 20:36
von Hyperion
jerch 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]
:twisted:
Also ehrlich gesagt legst Du zu viel Präzision in die Frage des OP 8)

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