How can I rotate this list of lists with python
numpy.rot90
can do that and is fast for large matrices such as images:
import numpy as np
grid = [['.', '.', '.', '.', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['0', '0', '0', '0', '.', '.'],
['0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '.'],
['0', '0', '0', '0', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
grid = np.rot90(grid, k=3)
print(grid)
# [['.' '.' '0' '0' '.' '0' '0' '.' '.']
# ['.' '0' '0' '0' '0' '0' '0' '0' '.']
# ['.' '0' '0' '0' '0' '0' '0' '0' '.']
# ['.' '.' '0' '0' '0' '0' '0' '.' '.']
# ['.' '.' '.' '0' '0' '0' '.' '.' '.']
# ['.' '.' '.' '.' '0' '.' '.' '.' '.']]
It's actually easier to do this with a one dimensional array than it is with a 2D array (edit: I was wrong, the zip
approach is pretty darn easy too, and the best IMO; leaving this for comparison), so just for fun, we'll convert to 1D, than rotate to a new 2D:
>>> from itertools import chain
>>> # Collapses to 1D
>>> grid1d = list(chain(*grid))
>>> # Rotates and rebuilds as 2D
>>> numcolumns = len(grid[0])
>>> rotated = [grid1d[i::numcolumns] for i in range(numcolumns)]
>>> print(*rotated, sep="\n")
['.', '.', '0', '0', '.', '0', '0', '.', '.']
['.', '0', '0', '0', '0', '0', '0', '0', '.']
['.', '0', '0', '0', '0', '0', '0', '0', '.']
['.', '.', '0', '0', '0', '0', '0', '.', '.']
['.', '.', '.', '0', '0', '0', '.', '.', '.']
['.', '.', '.', '.', '0', '.', '.', '.', '.']
Side-note: If you're on Python 2, that print
syntax would require a from __future__ import print_function
to work.
index magic:
>>> grid = [['.', '.', '.', '.', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['0', '0', '0', '0', '.', '.'],
['0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '.'],
['0', '0', '0', '0', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
>>> for i in range(len(grid[0])): #assuming they all have the same length
print (''.join(x[i] for x in grid))
..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....
or to save to a new grid:
>>> newgrid = []
>>> for i in range(len(grid[0])): #assuming they all have the same length
newgrid.append([x[i] for x in grid])
>>> newgrid
[['.', '.', '0', '0', '.', '0', '0', '.', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '.', '0', '0', '0', '0', '0', '.', '.'],
['.', '.', '.', '0', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '0', '.', '.', '.', '.']]
or one line:
>>> newgrid = [[x[i] for x in grid] for i in range(len(grid[0]))]
>>> newgrid
[['.', '.', '0', '0', '.', '0', '0', '.', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '.', '0', '0', '0', '0', '0', '.', '.'],
['.', '.', '.', '0', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '0', '.', '.', '.', '.']]
You can rotate your list of lists 90° using zip(*reversed(your_list))
like this:
grid = [['.', '.', '.', '.', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['0', '0', '0', '0', '.', '.'],
['0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '.'],
['0', '0', '0', '0', '.', '.'],
['.', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
print("\n".join(map("".join, zip(*reversed(grid)))))
Out:
..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....
Instead of reversed(grid)
you can use grid[::-1]
which also reverses the outer list, except it creates a copy of your list, which uses more memory (here I'm also using pprint
to show you what exactly your transposed list looks like):
from pprint import pprint
pprint(list(zip(*grid[::-1])))
[('.', '.', '0', '0', '.', '0', '0', '.', '.'),
('.', '0', '0', '0', '0', '0', '0', '0', '.'),
('.', '0', '0', '0', '0', '0', '0', '0', '.'),
('.', '.', '0', '0', '0', '0', '0', '.', '.'),
('.', '.', '.', '0', '0', '0', '.', '.', '.'),
('.', '.', '.', '.', '0', '.', '.', '.', '.')]
Which if you really wanted lists instead of tuples you could convert them back to list:
pprint([list(row) for row in zip(*reversed(grid))])
[['.', '.', '0', '0', '.', '0', '0', '.', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '0', '0', '0', '0', '0', '0', '0', '.'],
['.', '.', '0', '0', '0', '0', '0', '.', '.'],
['.', '.', '.', '0', '0', '0', '.', '.', '.'],
['.', '.', '.', '.', '0', '.', '.', '.', '.']]