Vergleich von 2 Listen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

@all: Seit wann hat denn der eingebettete Code keine Zeilennummerierung mehr?

Zum Problem:

Code: Alles auswählen

for [ex1[0]] in ... 
geht natürlich nicht. Hinter 'for' kann nur ein Bezeichner oder eine Folge von Bezeichnern stehen. Listenpaare enthält ja Tupel, also könnte man folgendes schreiben:

Code: Alles auswählen

for suchwert, zielwert in listenpaare: 
Das hat außerdem den Vorteil, daß man sofort sieht, was hinter dem Wert steckt. Alternativ kannst du auch weiterhin 'ex1' verwenden, mußt dann aber im Hinterkopf behalten, daß das ein Tupel ist. Weiter unten kommt dann die Abfrage, ob der Suchwert in external_faces enthalten ist. Je nach eingeschlagenem Weg würde das dann so aussehen:

Code: Alles auswählen

if suchwert in external_faces2:
oder

Code: Alles auswählen

 if ex1[0] in external_faces2: 
Such dir die in deinen Augen lesbarere Variante aus ;)

Statt 'in' zu verwenden, kannst du natürlich auch selbst über 'external_faces2' iterieren:

Code: Alles auswählen

for ex2 in external_faces2:
    if ex1[0] == ex2:   # Beachte: ex2 ist bereits der aktuelle Wert! Kein Indizieren nötig!
Bleibt das Problem, daß du in 'external_faces' den ggf. gefundenen Wert ersetzen mußt. Hierzu brauchst du nun aber den Index. Diesen kannst du z.B. über

Code: Alles auswählen

external_faces2.index(wert)
gewinnen, dies liefert dir aber immer nur den Index des ersten Auftretens des gesuchten Wertes. Was nicht unbedingt das ist, was du willst. (Es gibt allerdings noch einen zweiten Parameter für index -> mal in die Doku schauen).

Viel schöner ist der Einsatz von 'enumerate':

Code: Alles auswählen

for index, ex2 in enumerate(external_faces2):
    pass
Ich hoffe, es ist jetzt etwas klarer geworden.
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

na ja, noch nicht so ganz: wenn ich das richtig verstanden habe, soll mein Code so aussehen:

Code: Alles auswählen


for suchwert, zielwert in listenpaar:
    if ex1[0] in external_faces2:
        for ex2 in external_faces2:
            if ex1[0] == ex2:
                for index, ex2 in enumerate(external_faces2):
                    pass
                
print external_faces2


aber wo vergleiche ich denn da jetzt mit der List "listenpaar"? Was sind der suchwert und zielwert und wo kommen die später nochmals vor?
und wenn ich ihn durchlaufen
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

Bzw. so sieht mein Code aus

Code: Alles auswählen


for suchwert, zielwert in listenpaar:
    if suchwert in external_faces2:
        for ex2 in external_faces2:
            if ex1[0] == ex2:
                for index, ex2 in enumerate(external_faces2):
                    pass
                
print external_faces2

aber das Ergebnis ist dasselbe wie vorher
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Gib mal folgenden Code in die Interaktive Shell ein:

Code: Alles auswählen

eine_liste = ["ab", "cd", "ef"]
for wert in eine_liste:
    print wert
und

Code: Alles auswählen

eine_andere_liste = [ (1,2), (3,4), (5,6) ] # Struktur wie in 'Listenpaare'
for suchwert, zielwert in eine_andere_liste:
    print suchwert
    print zielwert
Verstehst du dadurch besser, wie die Schleife die Namen bindet?

Ansonsten: Du hast leider die verschiedenen Alternativen in einen Topf geworfen. Entweder, du nutzt das eingebaute 'in', oder du iterierst selbst über 'external_faces2'.
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

also sind hier der Suchwert immer der erste Eintrag in der Liste, der Zielwert der zweite. Ich gehe durch die Liste listenpaar durch und schau mir immer die Suchwerte an. Ich gehe mit ex2 durch die Liste der external_faces2 durch und vergleiche dann die beiden Listen: wenn die Einträge gleich sind dann... an der Stelle komme ich nicht mehr weiter. Eigentlich müsste ich hier doch die external_faces2-List überschreiben und zwar mit dem Zielwert der Liste listenpaar, oder?

Code: Alles auswählen

for suchwert, zielwert in listenpaar:
    for ex2 in external_faces2:
        if suchwert == ex2:
            for index, ex2 in enumerate(external_faces2):
                pass
                
print external_faces2

Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

An der Stelle, an der das 'pass' steht, müßtest du die Überschreibung vornehmen, richtig. Du iterierst allerdings doppelt über 'external_faces2'. Vielleicht kannst du das noch irgendwie zusammenfassen? Schau dir in der interaktiven Shell auch mal an, was die Funktion 'enumerate' eigentlich bewirkt.

Code: Alles auswählen

enumerate(eine_liste)
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

Gut, mit enumerate wird also dem Eintrag ex2 in external_faces2 der Index zugeordnet und durchnummeriert.
Anstelle von pass schreib ich jetzt ex2 = zielwert, weil er die Stelle ja durch den Zielwert ersetzen soll. Es passiert aber immer noch nichts...

Code: Alles auswählen


for suchwert, zielwert in listenpaar:
    for ex2 in external_faces2:
        if suchwert in external_faces2:
            for index, ex2 in enumerate(externa_faces2):
                ex2 = zielwert
                
print external_faces2

Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Hier im Forum verwenden wir gerne das Bild von den Post-its: 'ex2' ist ein Post-it, keine Schublade. Wenn du schreibst:

Code: Alles auswählen

ex2 = zielwert
hängst du ein weiteres Post-it an das Objekt, das der Wert von 'zielwert' darstellt. Es ist ein Name. Mehr nicht. An dem selben Wert (-objekt) hängen jetzt also zwei Namen: 'ex2' und 'zielwert'. Dein Problem ist, daß in der Liste immer noch der Bezug auf den alten Wert steht. Um diesen Bezug zu ändern, brauchst du den Index:

Code: Alles auswählen

liste[index] = wert
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

hmmm, wenn ichs so hinschreib, wie ich jetzt denke, dass es stimmt, dann gibt er mir eine Liste aus lauter "ef"-Einträgen aus:

Code: Alles auswählen



for suchwert, zielwert in listenpaar:
    for ex2 in external_faces2:
        if suchwert in external_faces2:
            for index, ex2 in enumerate(external_faces2):
                external_faces2[index]=wert
                
print external_faces2

listenpaar: [[6, 0], [14, 1], [2, 2], [6, 0], [6, 0], [50, 3], [6, 0], [28, 4], [2, 2], [28, 4], [28, 4], [40, 5], [2, 2], [40, 5], [0, 6], [40, 5], [40, 5], [4, 7], [44, 8], [40, 5], [52, 9], [6, 0], [6, 0], [60, 10], [60, 10], [28, 4], [60, 10], [68, 11], [68, 11], [28, 4], [40, 5], [68, 11], [44, 8], [68, 11], [82, 12], [6, 0], [88, 13], [6, 0], [60, 10], [88, 13], [88, 13], [68, 11], [102, 14], [68, 11]]

external_faces2: ['ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef', 'ef']

sehr seltsam...
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Du hast immer noch die unnötigerweise verdoppelte Schleife drin. Und starte mal deine Umgebung (IDLE oder was auch immer du nutzt) neu, um die Altlasten vom Ausprobieren zu entsorgen.
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

ja, ef ist jetzt draußen, war mein Fehler :-) - wie alles andere auch.

Code: Alles auswählen


for suchwert, zielwert in listenpaar:
    for index, ex2 in enumerate(external_faces2):
        if suchwert in external_faces2:
            #for index, ex2 in enumerate(external_faces2):
            external_faces2[index]=zielwert
                
print external_faces2


ich glaube so wäre die doppelte Schleife gelöst...
aber sieht immer nocht komisch aus :-)
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Naja, im Rahmen deiner augenblicklichen Möglichkeiten wäre das aber die Lösung. Auf die problematische, quadratische Laufzeit hat dich Blackjack ja schon angesprochen. Bei der Vergabe von Namen solltest du dich an die Konventionen halten, wie sie z.B. in PEP 8 beschrieben werden.

Ein etwas schönerer Ansatz (im Hinblick auf die Laufzeit), der allerdings nicht die bestehende Liste verändert, sondern eine neue erzeugt:

Code: Alles auswählen

replacement_map = dict(Listenpaare) # Besser: Gleich als Dictionary anlegen und 1:1 Zuordnungen rausnehmen
neue_liste = []
for wert in external_faces2:
    if wert in replacement_map:
        neue_liste.append(replacement_map[wert])
    else:
        neue_liste.append(wert)

print neue_liste
# ggf. external_faces2 = neue_liste[:]
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

replacement_map[wert] ist somit der "Zielwert" von vorhin, wenn ich das richtig sehe?
und über dict(listenpaar) wird die Liste in ein Dictionary umgewandelt, wobei der erste Eintrag immer der "Key" ist und der 2. der Wert? Sehe ich das richtig?
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Ja.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und noch schrittweise zusammengestaucht:

Code: Alles auswählen

replacement_map = dict(listenpaare)
neue_liste = []
for wert in external_faces2:
    wert = replacement_map.get(wert, wert)
    neue_liste.append(wert)

print neue_liste

Code: Alles auswählen

replacement_map = dict(listenpaare)
neue_liste = [replacement_map.get(wert, wert) for wert in external_faces_2]

print neue_liste
Sebastian
Das Leben ist wie ein Tennisball.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Super, dann habe ich ja heute auch noch was mitgenommen: Das '.get' kannte ich noch nicht. :D
BlackJack

Wobei man es sich mit dem `dict()` nicht ganz so einfach machen kann wenn ich die ursprüngliche Liste verstanden habe, weil dort erst der neue und dann der alte Wert in den inneren Listen steht. Die müsste man also noch tauschen.

Code: Alles auswählen

def main():
    external_faces = [0, 2, 2, 14, 4, 0, 14, 50, 44, 4, 50, 52, 52, 82, 82, 88,
                      88, 102, 102, 44]
    pairs = [[6, 0], [14, 1], [2, 2], [6, 0], [6, 0], [50, 3], [6, 0], [28, 4],
             [2, 2], [28, 4], [28, 4], [40, 5], [2, 2], [40, 5], [0, 6],
             [40, 5], [40, 5], [4, 7], [44, 8], [40, 5], [52, 9], [6, 0],
             [6, 0], [60, 10], [60, 10], [28, 4], [60, 10], [68, 11], [68, 11],
             [28, 4], [40, 5], [68, 11], [44, 8], [68, 11], [82, 12], [6, 0],
             [88, 13], [6, 0], [60, 10], [88, 13], [88, 13], [68, 11],
             [102, 14], [68, 11]]
    
    old2new = dict((b, a) for a, b in pairs)
    result = [old2new.get(x, x) for x in external_faces]
    print result
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

mmmh, das sieht ja alles schon sehr gut aus. Profis halt am Werk... und nicht solche Anfänger wie ich :-)

Wie muss ich denn dann weiter verfahren bei folgender Konstellation:

Liste1 --> listenpaar[6, 0], [14, 1], [2, 2],...
Liste2 --> liste_Koordinaten [0, XYZ], [14 XYZ], [1, XYZ],[2, XYZ], ...

jetzt sollen die beiden Listen verglichen werden: wenn der 0. Eintrag des Tupels in der liste_Koordinaten = 1. Eintrag des Tupels in der Liste listenpaar. Ist dies der Fall, dann soll in einer neuen Liste die entsprechende Koordinate XYZ eingefügt werden...

hierzu hab ich jetzt erstmal liste_Koordinaten in ein dictionary umgewandelt, dann folgt der Vergleich...

Code: Alles auswählen


replacement_map2 = dict(liste_Koordinaten) # umwandeln in dictionary
neue_liste2 = ()
for key in replacement_map2: #für alle Key-Werte der Koordinatenliste
    if key in replacement_map:    #wenn der Key-Wert in der Listenpaar-Liste vorkommt (aber an der Stelle Key, nicht bei Wert)
        neue_liste2.append(replacement_map[wert]) #dann schreibe in eine neue Liste die Koordinate XYZ raus
    else:
        neue_liste2.append(wert)

print neue_liste2


das ist jetzt sicher auch wieder Schwachsinn, aber ein Versuch immerhin wert...
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

hab mich vertippt: der 0. Eintrag des Tupels in listenpaare = 0. Eintrag des Tupels in Liste_koordinaten --> dann schreibe in neue liste den 1. Eintrag der liste_koordinaten (sprich das XYZ)
Michi_J
User
Beiträge: 110
Registriert: Samstag 7. August 2010, 08:35

auf einen Fehler bin auch noch draufgekommen:
in der else-Anweisung darf nichts mehr passieren.

Code: Alles auswählen


replacement_map2 = dict(liste_Koordinaten)
neue_liste2 = []
for key in replacement_map2:
    print key
    if key in internal_faces2:
        neue_liste2.append(replacement_map2[wert]) #füge Wert der Koordinate an neue_liste2 an
        print neue_liste2
    else:
        pass
print neue_liste2

so gibt mir der Code zwar die richtige Anzahl an Koordianten aus, aber er schreibt immer nur einen Wert rein. Wie kann ich erreichen, dass er immer den entsprechenden Wert der Koordinate hernimmt?

Danke.
Antworten