[英]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. 我在Reportlab中显示一个表,我想将它们显示为列。 As I understand it, RL only takes data for tables (Platypus) in the row form that I have above.
据我了解,RL只采用我上面的行格式表(Platypus)的数据。
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. 我可以使用循环来进行切换,但我觉得有一个列表理解会更快更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! 谢谢您的帮助!
itertools.izip_longest()
takes a fillvalue
argument. itertools.izip_longest()
接受一个fillvalue
参数。 On Python 3, it's itertools.zip_longest()
. 在Python 3上,它是
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')]
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']]
grid = [['a','b','c'], ['d','e'], [], ['f','g','h','i']]
i = 0
result = []
do_stop = False
while not do_stop:
result.append([])
count = 0
for block in grid:
try:
result[i].append(block[i])
except:
result[i].append('')
count = count +1
continue
if count ==len(grid):
result.pop(i)
do_stop = True
i = i + 1
print result
yet another way that I think is simpler if you can tolerate None values instead of empty strings: 如果你可以容忍None值而不是空字符串,我认为另一种方式更简单:
a = [['a','b','c'], ['d','e'], [], ['f','g','h','i']]
map(lambda *z: list(z), *a)
#[['a', 'd', None, 'f'], ['b', 'e', None, 'g'], ['c', None, None, 'h'], [None, None, None, 'i']]
map(lambda *z: [s if s else '' for s in z], *a)
要么
map(lambda *z: [('', s)[s>None] for s in z], *a)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.