Eso es un poco inteligente.
Primero, como se señaló en un comentario, en Python 3 zip()
devuelve un iterador, por lo que debe encerrar todo list()
para obtener una lista real, de modo que a partir de 2020 sea en realidad:
list(zip(*original[::-1]))
Aquí está el desglose:
[::-1]
- hace una copia superficial de la lista original en orden inverso. También podría usar reversed()
lo que produciría un iterador inverso sobre la lista en lugar de copiar la lista (más eficiente en memoria).
*
- hace que cada sublista de la lista original sea un argumento separado zip()
(es decir, descomprime la lista)
zip()
- toma un elemento de cada argumento y hace una lista (bueno, una tupla) a partir de ellos, y lo repite hasta que se agotan todas las sublistas. Aquí es donde realmente ocurre la transposición.
list()
convierte la salida de zip()
en una lista.
Entonces, asumiendo que tienes esto:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Primero obtienes esto (copia superficial, invertida):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
A continuación, cada una de las sublistas se pasa como argumento a zip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
consume repetidamente un elemento desde el principio de cada uno de sus argumentos y crea una tupla a partir de él, hasta que no hay más elementos, lo que da como resultado (después de que se convierte en una lista):
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
Y Bob es tu tío.
Para responder a la pregunta de @ IkeMiguel en un comentario sobre rotarlo en la otra dirección, es bastante sencillo: solo necesita revertir tanto las secuencias que entran zip
como el resultado. El primero se puede lograr quitando el [::-1]
y el segundo se puede lograr lanzando un reversed()
alrededor de todo. Dado que reversed()
devuelve un iterador sobre la lista, tendremos que poner list()
todo eso para convertirlo. Con un par de list()
llamadas adicionales para convertir los iteradores en una lista real. Entonces:
rotated = list(reversed(list(zip(*original))))
Podemos simplificar eso un poco usando la porción de "emoticón marciano" en lugar de reversed()
... entonces no necesitamos el exterior list()
:
rotated = list(zip(*original))[::-1]
Por supuesto, también puede simplemente girar la lista en el sentido de las agujas del reloj tres veces. :-)