En un programa que estoy escribiendo, surgió la necesidad de rotar una matriz bidimensional. Buscando la solución óptima, encontré este impresionante resumen que hace el trabajo:
rotated = zip(*original[::-1])
Lo estoy usando en mi programa ahora y funciona como se supone. Sin embargo, mi problema es que no entiendo cómo funciona.
Agradecería que alguien pudiera explicar cómo las diferentes funciones involucradas logran el resultado deseado.
python
multidimensional-array
paldepind
fuente
fuente
Respuestas:
Considere la siguiente lista bidimensional:
Vamos a desglosarlo paso a paso:
Esta lista se pasó a
zip()
utilizar el argumento de desembalar , de modo que loszip
extremos de llamada a ser el equivalente a esto:Con suerte, los comentarios dejan en claro lo que
zip
hace, agrupará elementos de cada entrada iterable en función del índice, o en otras palabras, agrupará las columnas.fuente
rotated = [list(r) for r in zip(*original[::-1])]
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 todolist()
para obtener una lista real, de modo que a partir de 2020 sea en realidad:Aquí está el desglose:
[::-1]
- hace una copia superficial de la lista original en orden inverso. También podría usarreversed()
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 separadozip()
(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 dezip()
en una lista.Entonces, asumiendo que tienes esto:
Primero obtienes esto (copia superficial, invertida):
A continuación, cada una de las sublistas se pasa como argumento a
zip
: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):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 unreversed()
alrededor de todo. Dado quereversed()
devuelve un iterador sobre la lista, tendremos que ponerlist()
todo eso para convertirlo. Con un par delist()
llamadas adicionales para convertir los iteradores en una lista real. Entonces:Podemos simplificar eso un poco usando la porción de "emoticón marciano" en lugar de
reversed()
... entonces no necesitamos el exteriorlist()
:Por supuesto, también puede simplemente girar la lista en el sentido de las agujas del reloj tres veces. :-)
fuente
zip
en una lista en Python 3.x!Hay tres partes para esto:
fuente
Solo una observación. La entrada es una lista de listas, pero la salida de la muy buena solución: rotated = zip (* original [:: - 1]) devuelve una lista de tuplas.
Esto puede ser un problema o no.
Sin embargo, se corrige fácilmente:
La composición de la lista o el mapa convertirán las tuplas interiores de nuevo en listas.
fuente
fuente
Yo mismo tuve este problema y encontré la gran página de wikipedia sobre el tema (en el párrafo "Rotaciones comunes":
https://en.wikipedia.org/wiki/Rotation_matrix#Ambiguities
Luego escribí el siguiente código, muy detallado para tener una comprensión clara de lo que está sucediendo.
Espero que le resulte útil profundizar más en la hermosa e inteligente frase que ha publicado.
Para probarlo rápidamente, puede copiarlo / pegarlo aquí:
http://www.codeskulptor.org/
fuente
Rotación en sentido antihorario (pivote estándar de columna a fila) como lista y dictado
Produce:
fuente
zip(*original[::-1])
funciona.