0

いくつかの条件に基づいて、フローの途中でジェネレーターの出力を「切り替える」必要があるタスクがあります。

無限のソースからデータを生成するジェネレータがあるとしましょう。ジェネレーターから 1GB のデータを読み取るたびに、出力を他のリーダーに切り替えます。

input = MyInfiniteGenerator()
Reader1(input) # does something with the first gigabyte of data
Reader2(input) # does something with the second gigabyte of data
...

出力を Reader1 から Reader2 に切り替えるときは、Reader1 を閉じる必要があります。リーダーの動作を変更することはできません。単に入力を繰り返すだけです。

この問題は、ローテーション ファイル ログに似ています。

4

2 に答える 2

1

必要な量だけを読み取る別のジェネレーターでジェネレーターをラップすることをお勧めします。itertools.islice仕事をうまくやるべきです:

import itertools

gen = someInfiniteGenerator()

while True:
    slice = itertools.islice(gen, 1000000) # reads one million items from gen
    reader = Reader(slice) # consumes all of the slice

これに関する唯一の潜在的な問題genは、終了した場合 (つまり、 がStopIteration発生した場合)、空のジェネレーターを取得した場合に Reader が反転しない限り、それを検出できないことです。これが不可能な場合は、何かを生成する前にジェネレーターに少なくとも 1 つのアイテムがあることを確認する追加レベルのジェネレーターを使用して回避できます。

class EmptyGenerator(Exception):
    pass

def notEmptyGen(gen):
    try:
        first = next(gen)
        yield first
    except StopIteration: # empty source generator
        raise EmptyGenerator()

    yield from gen
于 2012-12-08T15:00:28.337 に答える
0

次のようなことができます

input_chunk = (i for _, i in zip(xrange(chunk_size), input)) # `range` in Python3

または、おそらくより一般的には、

from itertools import takewhile    
input_chunk = takewhile(condition, input)

などにフィードinput_chunkしますReader1

condition引数を 1 つ取る関数 ( の項目) である必要がありますinput

また、 は組み込み関数inputの名前であり、それを変数名として使用するとシャドウすることに注意してください。

のドキュメントitertools.takewhile

于 2012-12-08T14:20:13.987 に答える