Python - Transpose List of Lists of various lengths - 3.3 easiest method
Asked Answered
O

3

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

In Python 2 If I have a list containing lists of variable lengths then I can do the following:

list(map(None,*a))

Result:

[(1, 4, 7), (2, 6, 8), (3, None, 9)]

In Python 3 None type is seemingly not accepted.

Is there, in Python 3, an as simple method for producing the same result.

Officiant answered 3/2, 2014 at 14:7 Comment(2)
How does list(map(None, *a)) work?Patrol
I found an answer herePatrol
P
9

You can use itertools.zip_longest in Python 3:

>>> from itertools import zip_longest
>>> list(zip_longest(*a))
[(1, 4, 7), (2, 6, 8), (3, None, 9)]
Pontefract answered 3/2, 2014 at 14:9 Comment(0)
P
0

You can also use list comprehensions to do this, which I guess should work regardless of the Python version:

max_len = max(len(i) for i in a)
[[i[o] if len(i) > o else None for i in a] for o in range(max_len)]

Output:

[[1, 4, 7], [2, 6, 8], [3, None, 9]]

This gives you the flexibility to do whatever you want in case of missing values.

max_len = max(len(i) for i in a)
[[i[o] for i in a if len(i) > o] for o in range(max_len)]

Output:

[[1, 4, 7], [2, 6, 8], [3, 9]]

Alternately, as suggested by @gboffi, you can do the following to save more time:

l = [len(i) for i in a]
[[i[o] for ix, i in enumerate(a) if l[ix] > o] for o in range(max(l))]
Patrol answered 7/11, 2014 at 13:34 Comment(1)
Is it feasible to remove the function call in the inner loop, as in l = [len(i) for i in a] [[i[o] for i in a if l[i] > o] for o in range(max(l))]?Reld
F
0
grid = [[1],
    [4,5,6],
    [7,8,9,10,12,25]]

i = 0
result = []
do_stop = False
while not do_stop:
    result.append([])
    for block in grid:
        try:
            result[i].append(block[i])
        except:
            continue
    if len(result[i]) == 0:
        result.pop(i)
        do_stop = True
    i = i + 1

print result
Faultfinder answered 25/3, 2018 at 12:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.