# Transpose list of lists

Let’s take:

``````l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
``````

The result I’m looking for is

``````r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

and not

``````r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
``````

Much appreciated

## Solution #1:

``````map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

For python 3.x users can use

``````list(map(list, zip(*l))) # short circuits at shortest nested list if table is jagged
list(map(list, itertools.zip_longest(*l, fillvalue=None))) # discards no data if jagged and fills short nested lists with None
``````

Explanation:

There are two things we need to know to understand what’s going on:

1. The signature of zip: `zip(*iterables)` This means `zip` expects an arbitrary number of arguments each of which must be iterable. E.g. `zip([1, 2], [3, 4], [5, 6])`.
2. Unpacked argument lists: Given a sequence of arguments `args`, `f(*args)` will call `f` such that each element in `args` is a separate positional argument of `f`.
3. `itertools.zip_longest` does not discard any data if the number of elements of the nested lists are not the same (homogenous), and instead fills in the shorter nested lists then zips them up.

Coming back to the input from the question `l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]`, `zip(*l)` would be equivalent to `zip([1, 2, 3], [4, 5, 6], [7, 8, 9])`. The rest is just making sure the result is a list of lists instead of a list of tuples.

## Solution #2:

One way to do it is with NumPy transpose. For a list, a:

``````>>> import numpy as np
>>> np.array(a).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

Or another one without zip:

``````>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

## Solution #3:

Equivalently to Jena’s solution:

``````>>> l=[[1,2,3],[4,5,6],[7,8,9]]
>>> [list(i) for i in zip(*l)]
... [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

## Solution #4:

just for fun, valid rectangles and assuming that m[0] exists

``````>>> m = [[1,2,3],[4,5,6],[7,8,9]]
>>> [[row[i] for row in m] for i in range(len(m[0]))]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
``````

## Solution #5:

Methods 1 and 2 work in Python 2 or 3, and they work on ragged, rectangular 2D lists. That means the inner lists do not need to have the same lengths as each other (ragged) or as the outer lists (rectangular). The other methods, well, it’s complicated.

## the setup

``````import itertools
import six

list_list = [[1,2,3], [4,5,6, 6.1, 6.2, 6.3], [7,8,9]]
``````

## method 1 — `map()`, `zip_longest()`

``````>>> list(map(list, six.moves.zip_longest(*list_list, fillvalue='-')))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
``````

`six.moves.zip_longest()` becomes

The default fillvalue is `None`. Thanks to @jena’s answer, where `map()` is changing the inner tuples to lists. Here it is turning iterators into lists. Thanks to @Oregano’s and @badp’s comments.

In Python 3, pass the result through `list()` to get the same 2D list as method 2.

## method 2 — list comprehension, `zip_longest()`

``````>>> [list(row) for row in six.moves.zip_longest(*list_list, fillvalue='-')]
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
``````

## method 3 — `map()` of `map()` — broken in Python 3.6

``````>>> map(list, map(None, *list_list))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]]
``````

This extraordinarily compact @SiggyF second alternative works with ragged 2D lists, unlike his first code which uses numpy to transpose and pass through ragged lists. But None has to be the fill value. (No, the None passed to the inner map() is not the fill value. It means there is no function to process each column. The columns are just passed through to the outer map() which converts them from tuples to lists.

Somewhere in Python 3, `map()` stopped putting up with all this abuse: the first parameter cannot be None, and ragged iterators are just truncated to the shortest. The other methods still work because this only applies to the inner map().

## method 4 — `map()` of `map()` revisited

``````>>> list(map(list, map(lambda *args: args, *list_list)))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]   // Python 2.7
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]] // 3.6+
``````

Alas the ragged rows do NOT become ragged columns in Python 3, they are just truncated. Boo hoo progress.

# Three options to choose from:

### 1. Map with Zip

``````solution1 = map(list, zip(*l))
``````

### 2. List Comprehension

``````solution2 = [list(i) for i in zip(*l)]
``````

### 3. For Loop Appending

``````solution3 = []
for i in zip(*l):
solution3.append((list(i)))
``````

### And to view the results:

``````print(*solution1)
print(*solution2)
print(*solution3)

# [1, 4, 7], [2, 5, 8], [3, 6, 9]
``````

## Solution #7:

``````import numpy as np
r = list(map(list, np.transpose(l)))
``````

## Solution #8:

Maybe not the most elegant solution, but here’s a solution using nested while loops:

``````def transpose(lst):
newlist = []
i = 0
while i < len(lst):
j = 0
colvec = []
while j < len(lst):
colvec.append(lst[j][i])
j = j + 1
newlist.append(colvec)
i = i + 1
return newlist
``````

## Solution #9:

`more_itertools.unzip()` is easy to read, and it also works with generators.

``````import more_itertools
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r))      # a list of lists
``````

or equivalently

``````import more_itertools
l = more_itertools.chunked(range(1,10), 3)
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r))      # a list of lists
``````

## Solution #10:

``````matrix = [[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3],
[1,2,3]]

rows = len(matrix)
cols = len(matrix[0])

transposed = []
while len(transposed) < cols:
transposed.append([])
while len(transposed[-1]) < rows:
transposed[-1].append(0)

for i in range(rows):
for j in range(cols):
transposed[j][i] = matrix[i][j]

for i in transposed:
print(i)
``````

## Solution #11:

One more way for square matrix. No numpy, nor itertools, use (effective) in-place elements exchange.

``````def transpose(m):
for i in range(1, len(m)):
for j in range(i):
m[i][j], m[j][i] = m[j][i], m[i][j]
``````

## Solution #12:

Here is a solution for transposing a list of lists that is not necessarily square:

``````maxCol = len(l[0])
for row in l:
rowLength = len(row)
if rowLength > maxCol:
maxCol = rowLength
lTrans = []
for colIndex in range(maxCol):
lTrans.append([])
for row in l:
if colIndex < len(row):
lTrans[colIndex].append(row[colIndex])
``````

## Solution #13:

``````    #Import functions from library
from numpy import size, array
#Transpose a 2D list
def transpose_list_2d(list_in_mat):
list_out_mat = []
array_in_mat = array(list_in_mat)
array_out_mat = array_in_mat.T
nb_lines = size(array_out_mat, 0)
for i_line_out in range(0, nb_lines):
array_out_line = array_out_mat[i_line_out]
list_out_line = list(array_out_line)
list_out_mat.append(list_out_line)
return list_out_mat
``````

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .