Python:将不均匀的行转换为列

时间:2012-12-15 15:21:43

标签: python list-comprehension reportlab

我有一个包含不均匀元素的列表列表:

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

我在Reportlab中显示一个表,我想将它们显示为列。据我了解,RL只以上面的行形式获取表格(Platypus)的数据。

我可以使用循环来进行切换,但我觉得有一个列表理解会更快更Pythonic。我也需要在用完元素的列中留一个空格。

所需产品将是:

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

编辑:示例应该是字符串,而不是数字

感谢您的帮助!

5 个答案:

答案 0 :(得分:11)

itertools.izip_longest()需要fillvalue个参数。在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)]

如果确实需要子列表而不是元组:

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

当然这也适用于字符串:

>>> 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')]

它甚至可以这样工作:

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

答案 1 :(得分:1)

这是另一种方式:

>>> map(lambda *z: map(lambda x: x and x or '', z), *l)
[['a', 'd', '', 'f'], ['b', 'e', '', 'g'], ['c', '', '', 'h'], ['', '', '', 'i']]

答案 2 :(得分:1)

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

答案 3 :(得分:0)

如果你能容忍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']]

答案 4 :(得分:0)

map(lambda *z: [s if s else '' for s in z], *a)

map(lambda *z: [('', s)[s>None] for s in z], *a)