是否有类似拉链的功能可以填充到最长的长度?
Posted
技术标签:
【中文标题】是否有类似拉链的功能可以填充到最长的长度?【英文标题】:Is there a zip-like function that pads to longest length? 【发布时间】:2010-11-19 14:55:26 【问题描述】:是否有一个像zip()
一样工作的内置函数,但它会填充结果,以便结果列表的长度是 longest 输入的长度而不是 最短的输入?
>>> 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)]
【问题讨论】:
【参考方案1】:在 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
一起使用。 feature of map
鲜为人知(但 map
在 Python 3.x 中发生了变化,因此这只适用于 Python 2.x)。
>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
【讨论】:
我们没有非 itertools Python 3 解决方案吗? @PascalvKooten 这不是必需的。itertools
无论如何都是内置的 C 模块。【参考方案2】:
对于 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)]
【讨论】:
如果你想让你的代码同时兼容python 2和python 3,你可以使用six.moves.zip_longest
来代替。【参考方案3】:
非 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)
【讨论】:
这适用于 micropython,谢谢@dansalmo!【参考方案4】:非 itertools 我的 Python 2 解决方案:
if len(list1) < len(list2):
list1.extend([None] * (len(list2) - len(list1)))
else:
list2.extend([None] * (len(list1) - len(list2)))
【讨论】:
【参考方案5】:除了接受的答案之外,如果您正在使用 可能但不应该长度不同的迭代,建议将 strict=True
传递给zip()
(从 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
参数,任何错误 导致不同长度的迭代将被静音, 可能表现为在另一部分中难以发现的错误 程序。
【讨论】:
【参考方案6】:我使用的是二维数组,但概念与使用 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]
【讨论】:
请解释为什么这段代码有效。或者为什么它是正确的答案以上是关于是否有类似拉链的功能可以填充到最长的长度?的主要内容,如果未能解决你的问题,请参考以下文章