イテレーターを複数回反復できないのはなぜですか?包括的な調査と解決策
次のコードを考えてみましょう:
def test(data): for row in data: print("first loop") for row in data: print("second loop")
データがリスト反復子やジェネレーター式などの反復子の場合、それを 2 回反復すると予期しない結果が生成されます。 :
>>> test(iter([1, 2])) first loop first loop >>> test((_ for _ in [1, 2])) first loop first loop
これらの例は、「最初のループ」を複数回出力しますが、「2 番目のループ」は決して出力しません。印刷された。この動作により、なぜ初回は反復が機能するのに、2 回目では機能しないのかという疑問が生じます。この制限にはどのように対処すればよいでしょうか?
イテレータと消費について
イテレータは、一度に 1 つの値を生成するオブジェクトです。反復の際、イテレーターは消費されます。つまり、一度通過すると、再度反復することはできません。ジェネレーター、ファイル オブジェクト、その他多くの反復可能なオブジェクトにも同じことが当てはまります。
この消費動作は、次のコード スニペットに例示されています。
data = [1, 2, 3] it = iter(data) next(it) # => 1 next(it) # => 2 next(it) # => 3 next(it) # => StopIteration
反復子が消費されると、生成する要素がなくなった場合の StopIteration 例外。 for ループのコンテキストでは、この例外によりループが初めて終了します。
回避策と代替アプローチ
同じデータを反復処理する必要がある場合複数回発生する場合は、いくつかの回避策が利用可能です:
1.リストの作成:
反復子の要素をリストに保存すると、必要なだけ何度でも反復できます:
data = list(it)
2 。独立したイテレータには tee() を使用します:
イテレータが多数の要素を処理する場合、リストの作成は非効率になる可能性があります。 itertools.tee() 関数を使用すると、単一のソースから複数の独立したイテレータを作成できます。
import itertools it1, it2 = itertools.tee(data, 2) # create as many as needed
これらの各イテレータは、他のイテレータに影響を与えることなく個別に走査できます。
3.シーケンスに変換:
セットなどの一部の反復子は、list() や tuple() などの関数を使用してシーケンスに変換できます。この変換により、複数回反復可能な新しいオブジェクトが作成されます。
data = list(sorted(my_set))
反復子の消費動作を理解し、適切な回避策を実装することで、必要なデータを確保しながら反復可能なオブジェクトの利点を享受できます。複数回の反復が必要です。
以上がイテレータを複数回反復できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。