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', '.', '.', '.', '.']]

Tags:

Python