rust-ssg/blog/posts/2023-10-03_rotate-a-matrix-in-python.rst

94 lines
2.3 KiB
ReStructuredText
Raw Normal View History

2023-10-14 18:03:36 +00:00
Rotate a Matrix in Python
#########################
:author: tyrel
:category: Tech
:tags: python
:status: published
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.
.. code-block:: python
>>> 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
.. code-block:: python
>>> 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.
.. code-block:: python
# 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)
.. code-block:: python
>>> # 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.
.. code-block:: python
# 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.
.. code-block:: python
>>> 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)]