是否有类似拉链的功能可以填充到最长的长度?

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+),也可以将 mapNone 一起使用。 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]

【讨论】:

请解释为什么这段代码有效。或者为什么它是正确的答案

以上是关于是否有类似拉链的功能可以填充到最长的长度?的主要内容,如果未能解决你的问题,请参考以下文章

是否有用于查找字符串中最长且不重复长度的子字符串的结构函数?

MySQL计算最长运行长度

一些结论总结

一些结论总结

仅获取猫鼬虚拟填充的长度

图遍历算法的应用(包括输出长度为l的路径最短最长路径)