Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python list transpose and fill

I have a list of lists such that the length of each inner list is either 1 or n (assume n > 1).

>>> uneven = [[1], [47, 17, 2, 3], [3], [12, 5, 75, 33]]

I want to transpose the list, but instead of truncating the longer list (as with zip) or filling the shorter lists with None, I want to fill the shorter lists with their own singular value. In other words, I'd like to get:

>>> [(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]

I can do this with a couple of iterations:

>>> maxlist = len(max(*uneven, key=len))
>>> maxlist
4
>>> from itertools import repeat
>>> uneven2 = [x if len(x) == maxlist else repeat(x[0], maxlist) for x in uneven]
>>> uneven2
[[1, 1, 1, 1], [47, 17, 2, 3], [3, 3, 3, 3], [12, 5, 75, 33]]
>>> zip(*uneven2)
[(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]

But is there a better approach? Do I really need to know maxlist in advance to accomplish this?

like image 505
kojiro Avatar asked May 16 '12 00:05

kojiro


People also ask

Can you transpose a list in Python?

You can transpose a two-dimensional list using the built-in function zip() . zip() is a function that returns an iterator that summarizes the multiple iterables ( list , tuple , etc.). In addition, use * that allows you to unpack the list and pass its elements to the function.

How do you transpose a list of strings in Python?

To transpose in Python, one can either use the FOR loop with nested loops or use the nested list method.

What does .T mean in Python?

The . T accesses the attribute T of the object, which happens to be a NumPy array. The T attribute is the transpose of the array, see the documentation.

How do you convert a list to an array in Python?

Method : Using array() + data type indicator This is an inbuilt function in Python to convert to array. The data type indicator “i” is used in case of integers, which restricts data type.


2 Answers

You can repeat one element list forever:

uneven = [[1], [47, 17, 2, 3], [3], [12, 5, 75, 33]]

from itertools import repeat

print zip(*(repeat(*x) if len(x)==1 else x for x in uneven))
like image 118
HYRY Avatar answered Oct 25 '22 13:10

HYRY


You could use itertools.cycle() instead:

>>> from itertools import cycle
>>> uneven3 = [x if len(x) != 1 else cycle(x) for x in uneven]
>>> zip(*uneven3)
[(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]

That means you don't need to know maxlist ahead of time.

like image 28
srgerg Avatar answered Oct 25 '22 13:10

srgerg