Tyrel's Blog

Code, Flying, Tech, Automation

Oct 03, 2023

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)]
 · · ·  python