Python ジェネレーター (Generator) についての深い理解
リスト生成を通じて簡単かつ直接リストを作成できますが、メモリの制約により、リストの容量は確実に制限されます。さらに、100 万個の要素を含むリストを作成すると、多くの記憶領域が必要になるだけでなく、最初の数要素にアクセスするだけで済む場合、後続の要素のほとんどが占有する領域が無駄になります。
では、リストの要素が特定のアルゴリズムに従って計算できれば、ループ中に後続の要素を継続的に計算できるでしょうか?これにより、完全なリストを作成する必要がなくなり、スペースが大幅に節約されます。 Python では、ループと計算を同時に行うこの仕組みをジェネレーターと呼びます。
ジェネレーターを作成するには、さまざまな方法があります。最初の方法は非常に簡単で、リスト生成式の [] を () に変更してジェネレーターを作成するだけです。はリスト、gen はジェネレーターです。
リストの各要素を直接出力できますが、ジェネレーターの各要素を出力するにはどうすればよいでしょうか?
それらを 1 つずつ出力したい場合は、ジェネレーターの next() メソッドを使用できます:
>>> mylist = [ x for x in range(1, 10)] >>> mylist [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> gen = (x for x in range(1,10)) >>> gen <generator object <genexpr> at 0x7f1d7fd0f5a0>
ジェネレーターは next() が呼び出されるたびにアルゴリズムを保存すると言いました。次の要素の値が計算され、最後の要素が計算されて要素がなくなるまで、StopIteration エラーがスローされます。
実際、 next() メソッドの代わりに for ループを使用できます。これは効率的なプログラミングのアイデアにより一致しています:>>> gen.next() 1 >>> gen.next() 2 >>> gen.next() 3 ... >>> gen.next() 9 >>> gen.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
>>> gen = ( x for x in range(1, 10)) >>> for num in gen: ... print num ... 1 2 3 4 5 6 7 8 9
Fi ボラッチ数列はリストを使用して書くことはできません生成されますが、関数を使用して簡単に出力できます:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
上記の関数は、フィボナッチ数列の最初の N 個の数値を出力できます:
def fib(max): n = 0 a, b = 0, 1 while n < max: print b a, b = b, a + b n = n + 1
よく見ると、次のことがわかります。 fib 関数は実際にはフィボナッチ数列の計算ルールを定義しており、最初の要素から開始して後続の要素を計算できます。このロジックは実際にはジェネレーターと非常によく似ています。
つまり、上記の関数はジェネレーターまであと 1 ステップです。 fib 関数をジェネレーターに変えるには、print b を yield b に変更するだけです。>>> fib(6) 1 1 2 3 5 8
これは、ジェネレーターを定義する別の方法です。関数定義に yield キーワードが含まれている場合、その関数はもはや通常の関数ではなく、ジェネレーターです:
def fib(max): n = 0 a, b = 0, 1 while n < max: yield b a, b = b, a + b n = n + 1
ここで、最も理解しにくいのは、ジェネレーターと関数の実行フローが異なることです。関数は順番に実行され、return ステートメントまたは関数ステートメントの最後の行に到達すると戻ります。ジェネレーターとなる関数は next() が呼び出されるたびに実行され、yield ステートメントに遭遇するとリターンし、再度実行されると最後に返された yield ステートメントから実行を継続します。
簡単な例として、数値 1、3、5 を順番に返すジェネレーターを定義します。>>> fib(6) <generator object fib at 0x104feaaa0>
実行中、odd は通常の関数ではなく、ジェネレーターであることがわかります。に遭遇すると、yield に達すると中断され、次回実行が続行されます。 yield を 3 回実行すると、それ以上実行する yield がなくなるため、next() が 4 回目に呼び出されたときにエラーが報告されます。
fib の例に戻ると、ループ中に yield を呼び出し続けると、中断され続けます。もちろん、ループを終了するにはループの条件を設定する必要があります。そうしないと、無限の数がリストされます。>>> def odd(): ... print 'step 1' ... yield 1 ... print 'step 2' ... yield 3 ... print 'step 3' ... yield 5 ... >>> o = odd() >>> o.next() step 1 1 >>> o.next() step 2 3 >>> o.next() step 3 5 >>> o.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
generator は非常に強力なツールであり、Python では、単純にリスト生成をジェネレーターに変更することも、関数を使用して複雑なロジック ジェネレーターを実装することもできます。
ジェネレーターの動作原理を理解するために、ジェネレーターは for ループ中に次の要素を継続的に計算し、適切な条件下で for ループを終了します。関数から変更されたジェネレーターの場合、return ステートメントに遭遇するか、関数本体の最後の行が実行されると、それがジェネレーターを終了する命令となり、それに応じて for ループが終了します。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

UvicornはどのようにしてHTTPリクエストを継続的に聞きますか? Uvicornは、ASGIに基づく軽量のWebサーバーです。そのコア機能の1つは、HTTPリクエストを聞いて続行することです...

Pythonでは、文字列を介してオブジェクトを動的に作成し、そのメソッドを呼び出す方法は?これは一般的なプログラミング要件です。特に構成または実行する必要がある場合は...
