0

Trying to figure out to to transpose a list of lists ( i believe this a matrix not sure.) I know there may be more advanced and concise ways of doing this but trying to limit myself to using what my course has covered so far.

grid = [['apples', 'oranges', 'cherries', 'banana'],
        ['Alice', 'Bob', 'Carol', 'David'],
        ['dogs', 'cats', 'moose', 'goose']]

i know how to do this by printing. I'd do it like this.

for j in range(len(grid[0])):
    for i in range(len(grid)):
        print(grid[i][j],end=' ')
    print('')

but I'm struggling to figure out how to do this by actually saving it to a variable. this saves it in the right order but I don't know what to add to separate it into different lists

newgrid = []
for j in range(len(grid[0])):
    for i in range(len(grid)):
        newgrid.append([grid[i][j])
    # list separation here

end result should be

grid = [['apples', 'Alice', 'dog'],
        ['oranges', 'Bob', 'cats'],
        ['cherries', 'Carol', 'moose'],
        ['banana', 'David', 'goose']]
sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • Does this answer your question? [Transpose list of lists](https://stackoverflow.com/questions/6473679/transpose-list-of-lists) – MartenCatcher Jan 22 '20 at 06:23

5 Answers5

1

You don't directly want to add it to the outer list newgrid. Instead you want to add it to the latest row. You can achieve this by appending an empty list to your outer list at every iteration of the outer for loop and then appending to this list from the inner one. Here is the correct code:

newgrid = []
for j in range(len(grid[0])):
    newgrid.append([])                    # <-- add a new row
    for i in range(len(grid)):
        newgrid[-1].append(grid[i][j])    # <-- note the [-1] to add it to the latest row of newgrid

For completeness, you can accomplish this trivially using unpacking and zip as follows:

newgrid = list(zip(*grid))

or if you want a list of lists instead of a list of tuples:

newgrid = list(map(list, zip(*grid)))
sshashank124
  • 31,495
  • 9
  • 67
  • 76
  • 1
    Adding to the more concise method, if you would like to avoid storing each individual row as tuples: `newgrid = [list(row) for row in zip(*grid)]` – Sayandip Dutta Jan 22 '20 at 06:23
  • thank you, the first solution was the one I was trying to come up with, I think zip is outside the boundaries of the course right –  Jan 22 '20 at 06:57
0

You can do it quickly with one line as follows:

ngrid = [[grid[i][j] for i in range(len(grid))] for j in range(len(grid[0]))]

Just swap the rows and columns

anthony yaghi
  • 532
  • 2
  • 10
0

If you want to do it in for loops, you just need to append a bit differently.

grid = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]
newgrid=[]
for j in range(len(grid[0])):
    newgridrow = []
    for i in range(len(grid)):
        newgridrow.append(grid[i][j])
    newgrid.append(newgridrow)

output is:

[['apples', 'Alice', 'dogs'],
 ['oranges', 'Bob', 'cats'],
 ['cherries', 'Carol', 'moose'],
 ['banana', 'David', 'goose']]

The idea is that now you have a "series of series", instead of just a series of objects. That's what makes it a 2D series.

0

The above methods are really good, But List comprehension is faster because it is optimized for the Python interpreter to spot a predictable pattern during looping. Besides the syntactic benefit of list comprehensions, they are often as fast or faster than equivalent use of map.

grid = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

transpose= [[grid[j][i] for j in range(len(grid))] for i in range(len(grid[0]))]
mohammed wazeem
  • 1,310
  • 1
  • 10
  • 26
0

Using for loops

def transpose(array):
    res = []
    for i in range(len(array[0])):
        tmp = []
        for row in array:
            tmp.append(row[i])
        res.append(tmp)
    return res

# and then:
transpose(grid)

Using list-expressions

this becomes:

def transpose(array):
    return [[row[i] for row in array] for i in range(len(array[0]))]

Using zip

You do it with

list(zip(*grid))

resulting in:

[('apples', 'Alice', 'dogs'),
 ('oranges', 'Bob', 'cats'),
 ('cherries', 'Carol', 'moose'),
 ('banana', 'David', 'goose')]

If you insist that all are lists and not tuples, define your own zip_ that gives result in lists:

def zip_(*args):
    return map(lambda *x: list(x), *args)

and then call using this zip_:

list(zip_(*grid))

resulting in:

[['apples', 'Alice', 'dogs'],
 ['oranges', 'Bob', 'cats'],
 ['cherries', 'Carol', 'moose'],
 ['banana', 'David', 'goose']]

Using numpy's in-built transpose() method

import numpy as np
np.array(grid).transpose().tolist()

which gives you also everything as standard lists. np.array() transforms grid to a numpy array, on which the method transpose() is applied. But since the outcome is a numpy array, you convert to standard lists structure applying tolist() method on it.

Gwang-Jin Kim
  • 9,303
  • 17
  • 30