Suppose I have
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
How can I get a result like so?
r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
I know how to get
r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
but I must have lists as elements of the result.
(or to limit each "column" to the length of the shortest input "row")
In Python 3.x, use:
# short circuits at shortest nested list if table is jagged:
list(map(list, zip(*l)))
In Python 2.x, use:
# short circuits at shortest nested list if table is jagged:
map(list, zip(*l))
There are two important things to understand here:
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])
.args
, f(*args)
will call f
such that each element in args
is a separate positional argument of f
. Given 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])
. See also: Expanding tuples into argumentsThe rest is just making sure the result is a list of lists instead of a list of tuples, by using map
to create a list from each tuple.
To pad shorter rows with None
values in the output, import itertools
(this is in the standard library), and then:
In Python 3.x, use:
list(map(list, itertools.zip_longest(*l, fillvalue=None)))
In Python 2.x, use:
list(map(list, itertools.izip_longest(*l, fillvalue=None)))