Rotate a Matrix in Python
I've been doing Advent of Code for a few years now, and every year I do it in my favorite language, Python. One thing that comes up a lot, is rotating matrices.
One way to do this, is to use Numpy, using np.rot90(mat), but not everyone wants to install Numpy just to do one small task. I know I don't always.
The way I always do it, that will support non-square matrixes, is to use zip.
>>> matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
>>> rotated = list(zip(*matrix[::-1]))
# And result is
[[7, 4, 1],
[8, 5, 2],
[9, 6, 3]]
We can break this down bit by bit.
This will copy the list, with a -1 step, resulting in a reverse order
>>> matrix[::-1]
[[7,8,9],
[4,5,6],
[1,2,3]]
Next we need to call zip in order to get the x-th item from each inner list, but first, we need to unpack it. If you'll notice, the unpacked version isn't wrapped with another list, which is what zip needs from us.
# Too many lists
>>> print(matrix[::-1])
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]
# Just right
>>> print(*matrix[::-1])
[7, 8, 9] [4, 5, 6] [1, 2, 3]
From there, we can pass this unpacked list of - in our case - three lists, to zip (and in Python 3 this returns a generator, so we need to call list again on it, or just use it)
>>> # Again, we get the rotated matrix
>>> list(zip(*matrix[::-1]))
[[7, 4, 1],
[8, 5, 2],
[9, 6, 3]]
Notes
Small note: If you run this, you will actually get a list of tuples, so you can map those back to a list, if you need to update them for any reason. I just wanted square brackets in my examples.
# This is just messy looking, so I didn't mention it until now
>>> list(map(list, zip(*matrix[::-1])))
As I mentioned, due to using zip this will work with non-square examples as well.
>>> matrix = [
... [1,2,3,4,5,6,7,8,9],
... [9,8,7,6,5,4,3,2,1],
... ]
>>> print(list(zip(*matrix[::-1])))
[(9, 1),
(8, 2),
(7, 3),
(6, 4),
(5, 5),
(4, 6),
(3, 7),
(2, 8),
(1, 9)]