是否有一个类似zip的函数可以在Python中填充最长的长度?


170

是否有一个内置功能可以像这样工作,zip()但是会填充结果,以便结果列表的长度是最长输入的长度而不是最短输入的长度

>>> a = ['a1']
>>> b = ['b1', 'b2', 'b3']
>>> c = ['c1', 'c2']

>>> zip(a, b, c)
[('a1', 'b1', 'c1')]

>>> What command goes here?
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

Answers:


243

在Python 3中,您可以使用 itertools.zip_longest

>>> list(itertools.zip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

您可以None使用与fillvalue参数不同的值进行填充:

>>> list(itertools.zip_longest(a, b, c, fillvalue='foo'))
[('a1', 'b1', 'c1'), ('foo', 'b2', 'c2'), ('foo', 'b3', 'foo')]

使用Python 2,你既可以使用itertools.izip_longest(Python的2.6+),也可以使用mapNone。这是的鲜为人知的功能map(但map在Python 3.x中有所更改,因此仅在Python 2.x中有效)。

>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

3
我们没有非itertools Python 3解决方案吗?
PascalVKooten

3
@PascalvKooten不需要。itertools无论如何是内置的C模块。
Antti Haapala'8

82

对于Python 2.6x,请使用itertools模块的izip_longest

对于Python 3,请zip_longest改用(不加i)。

>>> list(itertools.izip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

8
如果您想使您的代码同时兼容python 2和python 3,则可以six.moves.zip_longest改用。
Gamrix '16

5

非itertools Python 3解决方案:

def zip_longest(*lists):
    def g(l):
        for item in l:
            yield item
        while True:
            yield None
    gens = [g(l) for l in lists]    
    for _ in range(max(map(len, lists))):
        yield tuple(next(g) for g in gens)

2

non itertools我的Python 2解决方案:

if len(list1) < len(list2):
    list1.extend([None] * (len(list2) - len(list1)))
else:
    list2.extend([None] * (len(list1) - len(list2)))

0

我使用2d数组,但是使用python 2.x的概念相似:

if len(set([len(p) for p in printer])) > 1:
    printer = [column+['']*(max([len(p) for p in printer])-len(column)) for column in printer]

2
请添加有关此代码为何起作用的说明。还是为什么它是正确的答案
Suit Boy Apps
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.