14

他のいくつかの反復可能なオブジェクトからの要素を(それらを圧縮するのではなく)インターリーブできる関数がないことに気付きましたitertools(私には思えます):

def leaf(*args): return (it.next() for it in cycle(imap(chain,args)))
tuple(leaf(['Johann', 'Sebastian', 'Bach'], repeat(' '))) => ('Johann', ' ', 'Sebastian', ' ', 'Bach', ' ')

(編集) 私が尋ねる理由は、不必要な zip/flatten の発生を避けたいからです。

明らかに、 の定義leafは単純ですが、同じことを行う事前定義された関数がある場合は、それを使用するか、非常に明確なジェネレーター式を使用することをお勧めします。そのような関数は、itertools、または他のよく知られているライブラリ、または適切な慣用表現に組み込まれていますか?

編集 2: さらに簡潔な定義が可能です (functionalパッケージを使用):

from itertools import *
from functional import *

compose_mult = partial(reduce, compose)
leaf = compose_mult((partial(imap, next), cycle, partial(imap, chain), lambda *args: args))
4

3 に答える 3

15

zipビルトインを探していてitertools.chain.from_iterable、結果を平坦化します:

>>> import itertools
>>> list(zip(['Johann', 'Sebastian', 'Bach'], itertools.repeat(' ')))
[('Johann', ' '), ('Sebastian', ' '), ('Bach', ' ')]
>>> list(itertools.chain.from_iterable(_))
['Johann', ' ', 'Sebastian', ' ', 'Bach', ' ']

list良い出力を強制するためだけに使用したことに注意してください。標準の itertools を使用すると、代替の実装は次のleafようになります。

leaf = lambda *a: itertools.chain.from_iterable(itertools.izip(*a)) # Python 2.x
leaf = lambda *a: itertools.chain.from_iterable(zip(*a))            # Python 3.x
于 2012-01-07T12:57:48.003 に答える
8

itertools roundrobin () レシピは私の最初の選択肢でしたが、正確な例では、最短ではなく最長の iterable で停止するため、無限のシーケンスが生成されます。もちろん、それを修正するのは簡単です。たぶん、別のアプローチをチェックアウトする価値がありますか?

于 2012-01-07T15:36:04.960 に答える