0

Next() 呼び出しごとに任意の量のテキストを (文字列として) 受け取るジェネレーターを返すネットワーク ライブラリを使用しています。ここで、すべての Next() 呼び出しの結果を単純に連結した場合。標準的な英語のテキスト ドキュメントのように見えます。

各 Next() 呼び出しから返される文字列には複数の改行が含まれている可能性がありますが、まったく含まれていない可能性があります。返される文字列は必ずしも改行で終わるとは限りません。つまり、1 行のテキストが複数の Next() 呼び出しにまたがる可能性があります。

Next() が 1 行のテキストを返す必要がある 2 番目のライブラリでこのデータを使用しようとしています。ストリーム全体を読まないことは絶対に重要です。これは、数十ギガバイトのデータになる可能性があります。

この問題を解決する組み込みライブラリはありますか? そうでない場合、誰かがジェネレーターを作成するための最良の方法または問題を解決するための代替方法を提案できますか?

4

2 に答える 2

2

チャンクをプルダウンして行に分割するジェネレーター関数を作成します。最後の行が改行で終わっているかどうかわからないので、保存して次のチャンクに添付します。

def split_by_lines(text_generator):
    last_line = ""
    try:
        while True:
             chunk = "".join(last_line, next(text_generator))
             chunk_by_line = chunk.split('\n')
             last_line = chunk_by_line.pop()
             for line in chunk_by_line:
                 yield line
    except StopIteration: # the other end of the pipe is empty
        yield last_line
        raise StopIteration
于 2013-07-08T22:34:33.113 に答える
0

あなたの編集を読んだ後、任意の量のテキストを返すストリーム オブジェクトを変更できますか? たとえば、stream.next()メソッドには、ストリームが文字列を生成する方法がいくつかあり、それが呼び出されyieldsたときに発生します。.next()次のようなことができますか?

def next(self):
    if '\n' in self.remaining:
        terms = self.remaining.split('\n')
        to_yield, self.remaining = terms[0], ''.join(terms[1:])
        yield to_yield
    else:
        to_yield = self.remaining + self.generate_arbitrary_string()
        while '\n' not in to_yield:
            to_yield += self.generate_arbitrary_string()
        to_yield, self.remaining = terms[0], ''.join(terms[1:])
        yield to_yield        

この疑似コードは、ストリーム オブジェクトが を使用して任意の文字列を生成すると想定していますgenerate_arbitrary_string()。の最初の呼び出しでnext()は、self.remaining文字列は空である必要があるため、elseステートメントに移動します。そこでは、文字が見つかるまで任意の文字列を連結newlineし、連結された文字列を最初の文字で分割し、newline前半を生成して後半を に格納しremainingます。

以降の の呼び出しではnext()、最初に文字self.remainingが含まれているかどうかを確認しますnewline。もしそうなら、最初の行を生成し、残りを保存します。そうでない場合は、新しい任意の文字列を追加して、self.remaining上記のように続行します。

于 2013-07-08T22:33:26.200 に答える