The Python Oracle

Transpose list of lists

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Melt

--

Chapters
00:00 Question
00:27 Accepted answer (Score 516)
01:39 Answer 2 (Score 96)
01:53 Answer 3 (Score 81)
02:22 Answer 4 (Score 29)
02:39 Thank you

--

Full question
https://stackoverflow.com/questions/6473...

Accepted answer links:
[zip]: https://docs.python.org/library/function...
[Unpacked argument lists]: https://docs.python.org/tutorial/control...

Answer 3 links:
[NumPy transpose]: https://numpy.org/devdocs/reference/gene...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #list #transpose

#avk47



ACCEPTED ANSWER

Score 553


Python 3:

# short circuits at shortest nested list if table is jagged:
list(map(list, zip(*l)))

# discards no data if jagged and fills short nested lists with None
list(map(list, itertools.zip_longest(*l, fillvalue=None)))

Python 2:

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

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.




ANSWER 2

Score 112


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]]



ANSWER 3

Score 85


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

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

Or another one without zip (python < 3):

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

Or for python >= 3:

>>> list(map(lambda *x: list(x), *l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]



ANSWER 4

Score 29


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]]