Das ist ein kluges Stück.
Wie in einem Kommentar erwähnt, gibt Python 3 zunächst zip()
einen Iterator zurück. Sie müssen also das Ganze einschließen list()
, um eine aktuelle Liste wieder herauszubekommen. Ab 2020 ist es also tatsächlich:
list(zip(*original[::-1]))
Hier ist die Aufschlüsselung:
[::-1]
- erstellt eine flache Kopie der Originalliste in umgekehrter Reihenfolge. Könnte auch verwenden, reversed()
was einen umgekehrten Iterator über die Liste erzeugen würde, anstatt die Liste tatsächlich zu kopieren (speichereffizienter).
*
- macht jede Unterliste in der ursprünglichen Liste zu einem separaten Argument zip()
(dh entpackt die Liste)
zip()
- nimmt aus jedem Argument einen Punkt und erstellt daraus eine Liste (also ein Tupel) und wiederholt diese, bis alle Unterlisten erschöpft sind. Hier findet die Umsetzung tatsächlich statt.
list()
konvertiert die Ausgabe von zip()
in eine Liste.
Angenommen, Sie haben Folgendes:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Sie erhalten zuerst diese (flache, umgekehrte Kopie):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
Als nächstes wird jede der Unterlisten als Argument übergeben an zip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
verbraucht wiederholt ein Element vom Anfang jedes seiner Argumente und erstellt daraus ein Tupel, bis keine Elemente mehr vorhanden sind. Dies führt dazu (nachdem es in eine Liste konvertiert wurde):
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
Und Bob ist dein Onkel.
Um die Frage von @ IkeMiguel in einem Kommentar zum Drehen in die andere Richtung zu beantworten, ist es ziemlich einfach: Sie müssen nur die Sequenzen zip
und das Ergebnis umkehren . Das erste kann durch Entfernen des [::-1]
und das zweite durch Umwerfen reversed()
des Ganzen erreicht werden. Da reversed()
gibt einen Iterator über die Liste, müssen wir setzen list()
um , dass es zu konvertieren. Mit ein paar zusätzlichen list()
Aufrufen, um die Iteratoren in eine tatsächliche Liste umzuwandeln. So:
rotated = list(reversed(list(zip(*original))))
Wir können das ein wenig vereinfachen, indem reversed()
wir das "Martian Smiley" -Scheck verwenden, anstatt ... dann brauchen wir das Äußere nicht list()
:
rotated = list(zip(*original))[::-1]
Natürlich können Sie die Liste auch einfach dreimal im Uhrzeigersinn drehen. :-)