是否有类似zip的函数可以填充到最长长度?
有没有一个内置的函数,它的功能和 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)]
8 个回答
15
除了已经接受的答案,如果你在处理一些可能长度不同但实际上应该相同的可迭代对象,建议在使用zip()
时加上strict=True
这个参数(从Python 3.10开始支持)。
引用一下文档内容:
zip()
通常用于假设可迭代对象长度相等的情况。在这种情况下,建议使用strict=True
选项。它的输出和普通的zip()
是一样的:>>> list(zip(('a', 'b', 'c'), (1, 2, 3), strict=True)) [('a', 1), ('b', 2), ('c', 3)]
但是,与默认行为不同的是,它会检查可迭代对象的长度是否一致,如果不一致就会抛出一个
ValueError
错误:>>> list(zip(range(3), ['fee', 'fi', 'fo', 'fum'], strict=True)) Traceback (most recent call last): ... ValueError: zip() argument 2 is longer than argument 1
如果没有
strict=True
这个参数,任何导致可迭代对象长度不同的错误都会被忽略,可能会在程序的其他部分表现为一个难以发现的bug。
92
对于Python 2.6版本,可以使用itertools
模块里的izip_longest
。
而如果你使用的是Python 3,就用zip_longest
,注意这里没有前面的i
。
>>> list(itertools.izip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
389
在Python 3中,你可以使用itertools.zip_longest
这个功能。
>>> list(itertools.zip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
你可以通过使用fillvalue
这个参数,来填充一个不同于None
的值。
>>> 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及以上版本),或者你也可以用map
配合None
。这是map
的一个不太为人知的特性(不过map
在Python 3.x中有变化,所以这个方法只适用于Python 2.x)。
>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]