Outerzip/zip最长功能(具有多个填充值)

And*_*den 6 python

Python函数是否为"outer-zip",它是zip每个可迭代的不同默认值的扩展?

a = [1, 2, 3]   # associate a default value 0
b = [4, 5, 6, 7] # associate b default value 1

zip(a,b)  # [(1, 4), (2, 5), (3, 6)]

outerzip((a, 0), (b, 1)) = [(1, 4), (2, 5), (3, 6), (0, 7)]
outerzip((b, 0), (a, 1)) = [(4, 1), (5, 2), (6, 3), (7, 1)]
Run Code Online (Sandbox Code Playgroud)

我几乎可以使用map复制这个外部函数,但是None作为唯一的默认值:

map(None, a, b) # [(1, 4), (2, 5), (3, 6), (None, 7)]
Run Code Online (Sandbox Code Playgroud)

注1:内置zip函数需要任意数量的迭代,因此outerzip函数也是如此.(例如,一个人应该能够计算出outerzip((a,0),(a,0),(b,1))类似zip(a,a,b)map(None, a, a, b).)

注2:我说这个haskell问题的风格是"外拉链" ,但也许这不是正确的术语.

Sil*_*ost 7

它被称为izip_longest(zip_longest在python-3.x中):

>>> from itertools import izip_longest
>>> a = [1,2,3]
>>> b = [4,5,6,7]
>>> list(zip_longest(a, b, fillvalue=0))
[(1, 4), (2, 5), (3, 6), (0, 7)]
Run Code Online (Sandbox Code Playgroud)

  • `list(zip_longest(a, b, fillvalue=1 if len(a)>len(b) else 0))` (2认同)

ken*_*ytm 5

您可以进行修改zip_longest以支持一般可迭代的用例。

from itertools import chain, repeat

class OuterZipStopIteration(Exception):
    pass

def outer_zip(*args):
    count = len(args) - 1

    def sentinel(default):
        nonlocal count
        if not count:
            raise OuterZipStopIteration
        count -= 1
        yield default

    iters = [chain(p, sentinel(default), repeat(default)) for p, default in args]
    try:
        while iters:
            yield tuple(map(next, iters))
    except OuterZipStopIteration:
        pass


print(list(outer_zip( ("abcd", '!'), 
                      ("ef", '@'), 
                      (map(int, '345'), '$') )))
Run Code Online (Sandbox Code Playgroud)