Transpose a List of Lists

Transpose list of lists

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.

Transpose a Python list of lists

Use the common zip idiom:

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

Transpose a List of Lists

The following piece of code will create a list with i-th element of every list in before:

lapply(before, "[[", i)

Now you just have to do

n <- length(before[[1]]) # assuming all lists in before have the same length
lapply(1:n, function(i) lapply(before, "[[", i))

and it should give you what you want. It's not very efficient (travels every list many times), and you can probably make it more efficient by keeping pointers to current list elements, so please decide whether this is good enough for you.

Transpose nested list in python

Use zip with * and map:

>>> map(list, zip(*a))
[['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG', 'HHH', 'III'],
['1', '262', '86', '48', '8', '39', '170', '16', '4'],
['1', '56', '84', '362', '33', '82', '296', '40', '3'],
['10', '238', '149', '205', '96', '89', '223', '65', '5'],
['92', '142', '30', '237', '336', '140', '210', '50', '2']]

Note that map returns a map object in Python 3, so there you would need list(map(list, zip(*a)))

Using a list comprehension with zip(*...), this would work as is in both Python 2 and 3.

[list(x) for x in zip(*a)]

NumPy way:

>>> import numpy as np
>>> np.array(a).T.tolist()
[['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG', 'HHH', 'III'],
['1', '262', '86', '48', '8', '39', '170', '16', '4'],
['1', '56', '84', '362', '33', '82', '296', '40', '3'],
['10', '238', '149', '205', '96', '89', '223', '65', '5'],
['92', '142', '30', '237', '336', '140', '210', '50', '2']]

Transposing Lists - Python

There are a couple of ways to do it.

The first one is as follows:

print(list(map(list, zip(*a))))

another option is using numpy as follows:

print(np.array(a).T.tolist())

Another option is to use list comprehension as follows:

print([[row[i] for row in a] for i in range(len(a[0]))])

transpose a list of lists clojure

You are so close:

(defn transpose [& xs]
(apply map list xs))

transpose of a list of lists

let rec transpose list = match list with
| [] -> []
| [] :: xss -> transpose xss
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)

Taking advantage of syntax changes since answer first posted:

let rec transpose list = match list with
| [] -> []
| [] :: xss -> transpose xss
| (x::xs) :: xss ->
List.(
(x :: map hd xss) :: transpose (xs :: map tl xss)
)

Transpose ND list of lists

It can be done numpy-less and purely functional but it's not pretty:

from itertools import starmap, repeat

a = np.ones((1,3,1234,1624)).tolist()
b = list(map(list, map(map, repeat(list), map(starmap, repeat(zip), starmap(zip, a)))))
np.shape(b)
# (1, 1234, 1624, 3)


Related Topics



Leave a reply



Submit