ホームページ >バックエンド開発 >Python チュートリアル >Python - ジェネレーターの詳細説明
リスト生成では、リストを直接作成できます。ただし、メモリの制約により、リストの容量には確実に制限があります。さらに、100 万個の要素を含むリストを作成すると、大量の記憶領域が必要になるだけでなく、最初の数要素にアクセスするだけで済む場合、後続の要素のほとんどが占有する領域が無駄になります。では、リストの要素を特定のアルゴリズムに従って計算できれば、ループ中に後続の要素を継続的に計算できるでしょうか。これにより、完全なリストを作成する必要がなくなり、スペースが大幅に節約されます。 Python では、ループと計算を同時に行うこの仕組みをジェネレーター: ジェネレーターと呼びます。
ジェネレーターを作成するには、さまざまな方法があります。 1つ目の方法はとても簡単で、リスト生成の[ ]を( )に変えるだけです
LとGの作成の違いは一番外側の[ ]と( )だけで、Lはリスト、Gは生成デバイスです。 L の各要素を直接出力することはできますが、G の各要素を出力するにはどうすればよいでしょうか?それらを 1 つずつ出力したい場合は、 next() 関数を通じてジェネレーターの次の戻り値を取得できます:
ジェネレーター 保存されるのはアルゴリズムです。 next(G) が呼び出されるたびに、最後の要素が計算されるまで G の次の要素の値が計算され、要素がなくなると StopIteration 例外がスローされます。 。もちろん、この種の next() の連続呼び出しは実際には異常です。ジェネレーターも反復可能なオブジェクトであるため、正しい方法は for ループを使用することです。したがって、ジェネレーターを作成した後は、基本的に next() を呼び出すことはありませんが、for ループを通じて反復処理するため、StopIteration 例外を気にする必要はありません。
ジェネレーターは非常に強力です。計算アルゴリズムが比較的複雑で、リスト生成と同様の for ループを使用して実装できない場合は、関数を使用して実装することもできます。
たとえば、有名なフィボナッチ数列では、最初と 2 番目の数値を除き、最初の 2 つの数値を加算することで任意の数値を得ることができます:
1, 1, 2, 3, 5 , 8, 13, 21, 34 , ...
フィボナッチ数列はリスト生成では書けませんが、関数を使って簡単に出力できます:
よく見るとわかります。 fib 関数は実際にはフィボナッチ数列の計算ルールを定義しており、最初の要素から開始して後続の要素を計算できます。このロジックは実際にはジェネレーターと非常によく似ています。
言い換えれば、上記の関数はジェネレーターまであと 1 ステップです。 fib 関数をジェネレーターに変えるには、print(b) を変更して b を生成します:
for ループを使用してジェネレーターを実行したところ、ジェネレーターの return ステートメントの戻り値を取得できないことがわかりました。戻り値を取得したい場合は、StopIteration エラーをキャプチャする必要があります。戻り値は、StopIteration の値に含まれています:
例: yield が実行されると、gen 関数は一時的に保存され、i の値を返します。temp は次回 c.send("python") によって送信された値を受け取ります。これは c.next と同等です。 () c.send(None)
next関数を使用
__next__()メソッドを使用
送信を使用する
実行結果:
マルチタスクをシミュレートする方法の 1 つ: コルーチン
概要
ジェネレーターはこのような function は、最後に返されたときの関数本体内の位置を記憶します。ジェネレーター関数の 2 番目 (または n 番目) の呼び出しは、関数の途中にジャンプし、すべてのローカル変数は前の呼び出しから変更されないままになります。
ジェネレーターはデータの状態を「記憶」するだけではなく、フロー制御構造内の位置も「記憶」します (命令型プログラミングでは、この構造は単なるデータ値ではありません)。
ジェネレーターの特徴:
1. メモリを節約します。
2. 次の呼び出しに反復するときに、使用されるパラメーターは最初から保持されているものです。つまり、すべての関数呼び出しのパラメーターは次のとおりです。新しく作成されるのではなく、最初に呼び出されたときにすべてが保持されます
反復は、コレクション要素にアクセスする方法です。イテレータは、トラバースの位置を記憶するオブジェクトです。イテレータ オブジェクトは、コレクションの最初の要素からアクセスを開始し、すべての要素がアクセスされるまでアクセスします。イテレータは前方にのみ進むことができ、後方には進むことができません。
for ループに直接作用するデータ型は次のとおりです。
1 つのタイプは list、tuple、dict、set、str などのコレクション データ型です。ジェネレーター (ジェネレーターおよび yield 付きジェネレーター関数を含む)。
for ループで直接使用できるこれらのオブジェクトは、まとめて反復可能オブジェクト (Iterable) と呼ばれます。
2. 反復可能かどうかを判断する
3. イテレータ
概要
・forループで使用できるすべてのオブジェクトはIterable型です。
・next()関数で使用できるすべてのオブジェクトはIterator型です
・リスト、 dict、str などは Iterable ですが、Iterator ではありませんが、 iter() 関数を通じて Iterator オブジェクトを取得できます。
· 目的は、コレクションを使用するときに占有されるコンテンツを減らすことです。
1. 関数リファレンス
以上がPython - ジェネレーターの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。