Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: transposing uneven rows into columns

I have a list of lists with uneven numbers of elements:

[['a','b','c'], ['d','e'], [], ['f','g','h','i']]

I'm displaying a table in Reportlab, and I want to display those as columns. As I understand it, RL only takes data for tables (Platypus) in the row form that I have above.

I can use a loop to make the switch, but I feel like there's a list comprehension that would be faster and more Pythonic. I'll need a blank space in the columns that run out of elements, too.

The desired product would be:

[['a','d','','f'],['b','e','','g'],['c','','','h'],['','','','i']]

EDIT: the example should be string, rather than numbers

Thanks for the help!

like image 897
DeltaG Avatar asked Dec 11 '22 19:12

DeltaG


2 Answers

itertools.izip_longest() takes a fillvalue argument. On Python 3, it's itertools.zip_longest().

>>> l = [[1,2,3], [4,5], [], [6,7,8,9]]
>>> import itertools
>>> list(itertools.izip_longest(*l, fillvalue=""))
[(1, 4, '', 6), (2, 5, '', 7), (3, '', '', 8), ('', '', '', 9)]

If you do need sublists instead of tuples:

>>> [list(tup) for tup in itertools.izip_longest(*l, fillvalue="")]
[[1, 4, '', 6], [2, 5, '', 7], [3, '', '', 8], ['', '', '', 9]]

Of course this also works for strings:

>>> l = [['a','b','c'], ['d','e'], [], ['f','g','h','i']]
>>> import itertools
>>> list(itertools.izip_longest(*l, fillvalue=""))
[('a', 'd', '', 'f'), ('b', 'e', '', 'g'), ('c', '', '', 'h'), ('', '', '', 'i')]

It even works like this:

>>> l = ["abc", "de", "", "fghi"]
>>> list(itertools.izip_longest(*l, fillvalue=""))
[('a', 'd', '', 'f'), ('b', 'e', '', 'g'), ('c', '', '', 'h'), ('', '', '', 'i')]
like image 138
Tim Pietzcker Avatar answered Dec 26 '22 22:12

Tim Pietzcker


Here is another way:

>>> map(lambda *z: map(lambda x: x and x or '', z), *l)
[['a', 'd', '', 'f'], ['b', 'e', '', 'g'], ['c', '', '', 'h'], ['', '', '', 'i']]
like image 29
garst Avatar answered Dec 26 '22 23:12

garst