To sprytne rozwiązanie.
Po pierwsze, jak zauważono w komentarzu, w Pythonie 3 zip()
zwraca iterator, więc musisz załączyć całość, list()
aby uzyskać rzeczywistą listę z powrotem, więc od 2020 r.
list(zip(*original[::-1]))
Oto podział:
[::-1]
- sporządza płytką kopię oryginalnej listy w odwrotnej kolejności. Można również użyć, reversed()
który utworzyłby odwrotny iterator po liście zamiast kopiowania listy (bardziej wydajna pamięć).
*
- sprawia, że każda podlista w oryginalnej liście jest oddzielnym argumentem zip()
(tzn. rozpakowuje listę)
zip()
- pobiera jedną pozycję z każdego argumentu i tworzy z nich listę (cóż, krotkę) i powtarza, aż wszystkie podlisty zostaną wyczerpane. W tym miejscu faktycznie zachodzi transpozycja.
list()
konwertuje wynik programu zip()
na listę.
Zakładając, że masz to:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Najpierw dostajesz to (płytka, odwrócona kopia):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
Następnie każda z podlist jest przekazywana jako argument do zip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
wielokrotnie zużywa jeden element od początku każdego ze swoich argumentów i tworzy z niego krotkę, aż nie będzie już żadnych elementów, w wyniku czego (po przekonwertowaniu na listę):
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
Bob jest twoim wujem.
Aby odpowiedzieć na pytanie @ IkeMiguel w komentarzu na temat obracania go w innym kierunku, jest to całkiem proste: wystarczy odwrócić zarówno sekwencje, które wchodzą, jak zip
i wynik. Pierwszą można osiągnąć, usuwając, [::-1]
a drugą, rzucając reversed()
wokół całości. Ponieważ reversed()
zwraca iterator na liście, będziemy musieli go list()
obejść , aby ją przekonwertować. Z kilkoma dodatkowymi list()
wywołaniami, aby przekonwertować iteratory na rzeczywistą listę. Więc:
rotated = list(reversed(list(zip(*original))))
Możemy to nieco uprościć, używając plastra „marsjańskiej buźki” zamiast reversed()
… wtedy nie potrzebujemy zewnętrznego list()
:
rotated = list(zip(*original))[::-1]
Oczywiście możesz też po prostu trzykrotnie obrócić listę w prawo. :-)