Seite 1 von 1

Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:20
von Peak_me
huhu!


Ich habe zwei Arrays. Die Elemente, die in beiden Arrays vorkommen, sollen von einem entfernt werden.
Das habe ich so gelöst:

Code: Alles auswählen

x=[1,2,3]
y=[9,8,7,1]

for c in range(len(y)):
    if y[c] in x:
        del y[c]
Das funktioniert auch.
Doch wenn ich es in mein Hauptprogramm einbinde, kommt die Meldung
if umgebung[c] in kombi:
IndexError: list index out of range


"umgebung" entspricht "y" und
"kombi" sieht wie "x" aus.

Das alles ist in mehreren ineinander geschachtelten Schleifen eingebaut, sodass ich nicht dahinter komme, wo der Fehler liegt.
Als isoliertes Programm funktioniert es ja...
Ich denke, dass dadruch, dass ein Element von y entfernt wird, die Schleife ja einmal zu lange durchläuft, da sie ja mit len(y) gestartet wurde und da y noch ein Element länger war.

Ich habe alles mögliche probiert, um den Fehler zu finden... Ich habe Ausgaben an allen möglichen Stellen eingebaut, um die jeweiligen Zwischenergebnisse zu überprüfen... Alles läuft nach Plan bis zu dieser Stelle...
Wenn ich

Code: Alles auswählen

x=[1,2,3]
y=[9,8,7,1]

for c in range(len(y)):
    if y[c] in x:
        1+1
        #del y[c]
durchlaufen lasse, gibt es keinen Fehler im Hauptprogramm. Es muss also an einem Überlauf durch das Entfernen liegen.

Hat jemand irgendwelche Ideen?
Vielleicht eine Alternative, wie man aus einem Array alle Elemente entfernen kann, die in einem anderen Array enthalten sind?
Vielleicht gibt es mit einer Alternativlösung kein Problem mit dem Überlauf...

Mir ist noch eine (wenn auch sehr unelegante) Möglichkeit eingefallen, wie ich das Probelm umgehen könnte.
Dazu fehlt mir aber ein Befehl.
a.remove(b) entfernt ja nur das erste b und nicht alle b.
Ich brauche aber einen Befehl, der alle b aus a entfernt.
Wie heißt der?


Gruß
Paul

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:30
von EyDu
Du darfst nichts aus Listen löschen durch die du gerade iterierst.

Die einfachste Lösung: Einfach eine neue Liste erstellen. Schau dir dazu mal List Comprehensions (oder alternativ die filter-Funktion) und Mengen an.

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:35
von Rebecca
Dein erstes Codebeispiel funktioniert nur zufaellig, da das zu loeschende Element (die 1) in y als letztes steht. Das Problem ist, das du die Liste wahrend der Iteration veranderst: Du machst die Liste kuerzer, aber die for-Schleife geht noch ueber die urspruengliche Laenge.

Ausserdem ist for c in range(len(y)) unschoen, iteriere direkt ueber die Elemente!

Eine Loesung waere, eine dritte Liste in der Schleife neu zu erstellen. Falls x und y jeweils keine doppelten Elemente enthalten koennen, ginge es auch so:

Code: Alles auswählen

x = [1, 2, 3]
y = [1, 9, 8, 7]
for i in set(x) & set(y):
    y.remove(i)
EDIT: Verdammt, wie bekomme ich den ein einfaches Und-Zeichen in den Code? Der macht mir da html draus... :K

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:39
von jbs

Code: Alles auswählen

from operator import contains
from itertools import ifilterfalse
from functools import partial

l1 = range(4)
l2 = range(2,6)

print list(ifilterfalse(partial(contains, l2), l1))


Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:45
von pillmuncher
Ich würde es so machen:

Code: Alles auswählen

for each in x:
    while each in y:
        y.remove(each)
oder gleich deklarativ, also so:

Code: Alles auswählen

y = [each for each in y if each not in x]
[edit] if durch while ersetzt, damit alle und nicht nur jedes erste Vorkommen eines Elements aus x in y gelöscht werden.[/edit]

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 15:55
von Hyperion
Was spricht gegen Mengen?

Code: Alles auswählen

In [18]: x = [1,2,3]

In [19]: y = [9,8,7,1]

In [20]: sx = set(x)

In [21]: sy = set(y)

In [22]: sy - sx
Out[22]: set([7, 8, 9])

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 16:34
von pillmuncher
Hyperion hat geschrieben:Was spricht gegen Mengen?
Solange die Reihenfolge oder die Frage, ob es Duplikate geben darf, keine Rolle spielt: nichts :)

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 16:37
von BlackJack
Gegen Mengen spricht vielleicht die Reihenfolge. Wenn die erhalten bleiben soll:

Code: Alles auswählen

tmp = set(x)
y = [e for e in y if e not in tmp]

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 21:13
von bords0
Außer der Reihenfolge könnte noch sein, dass nicht alle Elemente hashable sind.

Davon abgesehen ist BlackJacks Lösung m.E. die kanonische.

Re: Doppelte finden

Verfasst: Mittwoch 16. Juni 2010, 23:26
von Peak_me
vielen Dank wiedereinmal für eure schnelle und qualifizierte Hilfe!

Ich habe pillmuchers Lösung verwendet.
Die anderen durchblicke ich nicht vollständig bzw. die verwendeten Befehle sind mir unbekannt.
Z.Z ist Python aber mehr Mittel zum Zweck um ein Problem zu lösen. Wenn ich damit durch bin, kann Python mal kurz Selbstzweck sein und ich kann mich mit den neuen Sachen beschäftigen.

Jetzt bin ich nur froh, dass mein riesen Programm langsam immer kompletter wird und das tut, was es soll :)