11

zipiterableごとに異なるデフォルト値を持つ拡張である「outer-zip」というPython関数はありますか?

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)]

mapを使用してこのouterzip関数をほぼ複製できますがNone唯一のデフォルトとして:

map(None, a, b) # [(1, 4), (2, 5), (3, 6), (None, 7)]

注 1: 組み込みzip関数は、任意の数の iterable を使用するため、outerzip関数も使用する必要があります。(例えば、と とouterzip((a,0),(a,0),(b,1))同様に計算できるはずです。)zip(a,a,b)map(None, a, a, b)

注 2:この haskell questionのスタイルで「outer-zip」と言いますが、おそらくこれは正しい用語ではありません。

4

3 に答える 3

11

izip_longest( zip_longestpython-3.x では)と呼ばれます:

>>> from itertools import zip_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)]
于 2012-10-26T11:14:57.323 に答える
4

一般的なイテラブルのユースケースをサポートするように変更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'), '$') )))
于 2012-10-26T11:46:02.023 に答える
2

この関数は、入力された各リストを拡張して圧縮することで定義できます。

def outerzip(*args):
    # args = (a, default_a), (b, default_b), ...
    max_length = max( map( lambda s: len(s[0]), args))
    extended_args = [ s[0] + [s[1]]*(max_length-len(s[0])) for s in args ]
    return zip(*extended_args)

outerzip((a, 0), (b, 1)) # [(1, 4), (2, 5), (3, 6), (0, 7)]
于 2012-10-26T11:28:31.767 に答える