verschachtelte Listen "verdrehen"?

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.
Antworten
martin86_mu
User
Beiträge: 16
Registriert: Montag 10. März 2008, 15:51

Hi,

ich möchte folgende Operation auf eine Liste der Länge x , die jeweils als Elemente wieder Listen der Länge y besitzt andwenden:

liste1 = [ [ A1, A2, A3] , [ B1, B2, B3] ]

--> liste2 = [ [A1, B1], [A2, B2], [A3, B3] ]

Ich bekomm leider keine saubere Lösung hin, hab aber noch ein Problem:
ich weiss irgendwie nicht genau, wie ich mein problem mit "fachbegriffen" beschreiben kann damit ich danach erfolgreich suchen kann (deshalb vielleicht auch ein etwas verwirrender Titel). Ich meine, dass ich dieses Problem schon mal hier im Forum gelesen habe, find aber keinen post.

Ich hoffe jemand kann mir helfen, gruß

Martin
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Code: Alles auswählen

[[x, y] for x, y in zip(liste1[0], liste1[1])]
Wenn es auch tuple sein dürfen:

Code: Alles auswählen

zip(liste1[0], liste1[1])
HTH
Christian
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Und händisch:

Code: Alles auswählen

def assert_equal(a,b):
    assert a == b, "%s != %s" % (a,b)

liste1 = [["a1", "a2",  "a3"], ["b1", "b2", "b3"]]
liste2 = []

# nochmal pruefen, ob 'liste1' auch soweit korrekt ist
# kann man natürlich auch in der nachfolgenden for-schleife integrieren,
# oder ganz weglassen, wenn man seiner Basis-Liste traut :D
[ assert_equal(len(elem), len(liste1[0])) for elem in liste1 ]

# nun die Kreuzverknüpfung an sich
for index in range(len(liste1[0])):
    liste2.append([ elem[index] for elem in liste1])
Das Resultat sah dann wie folgt aus:

Code: Alles auswählen

>>> print liste2
[['a1', 'b1'], ['a2', 'b2'], ['a3', 'b3']]
Sicher, nicht so kurz, bündig und performant wie CM's Variante, aber es tut's auch ;).

>>Masaru<<
martin86_mu
User
Beiträge: 16
Registriert: Montag 10. März 2008, 15:51

Hi, vielen dank an euch beide. Ich werd wohl den ' zip ' Befehl benutzen in Verbindung mit der (für meine Zwecke) sehr nützlichen Methode assert_equal. gruß [/quote]
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Eins dann aber noch ... die "zip"-Variante, funktioniert in der Form nur bei einer Liste "liste1", wenn diese auch genau zwei Unterlisten hat.

Bei drei Unterlisten funxt die Kreuzung leider schon nicht mehr:

Code: Alles auswählen

>>> liste1 = [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]
>>> liste2 = [[x, y] for x, y in zip(liste1[0], liste1[1])]
>>> print liste2
[['a1', 'b1'], ['a2', 'b2'], ['a3', 'b3']] # :(
Da ist die For-Schleife mit dem Index-Geraffel einiges flexibler ;):

Code: Alles auswählen

>>> liste1 = [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]
>>> liste2 = []
>>> for index in range(len(liste1[0])):
... 	liste2.append([ elem[index] for elem in liste1])
... 	
>>> print liste2
[['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']] # :)
BlackJack

@martin86_mu: In der Mathematik ist für das vertauschen von Zeilen und Spalten einer Matrix der Begriff "transponieren" üblich.

Man kann auch diesen netten "Trick" anwenden:

Code: Alles auswählen

In [3]: liste
Out[3]: [['A1', 'A2', 'A3'], ['B1', 'B2', 'B3']]

In [4]: zip(*liste)
Out[4]: [('A1', 'B1'), ('A2', 'B2'), ('A3', 'B3')]

In [5]: map(list, zip(*liste))
Out[5]: [['A1', 'B1'], ['A2', 'B2'], ['A3', 'B3']]
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

... funktioniert folglich auch mit beliebiger Anzahl an inneren Listen :).
martin86_mu
User
Beiträge: 16
Registriert: Montag 10. März 2008, 15:51

@Blackjack Ah ok danke irgendwie hab ich die Analogie von verschachtelten Listen zu Matrizen zuvor nicht wirklich realisiert. Thx
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Wenn es um Methoden geht, die eine "echte" Matrix betreffen, kannst Du auch auf numpy ausweichen. Dort ist das und viel mehr bereits implementiert.

edit: Dummen Rechtschreibfehler korrigiert.
Antworten