no-image

【Python 】ジェネレーターイテレーターについて

ジェネレーターイテレーターとは

変数(これ)=ジェネレータ関数 

でいう左辺、つまり、ジェネレータ関数を変数に収めたものです。

ジェネレータ関数は後述。

 

一般に関数の戻り値は、関数内で一通り計算し終わった後にreturn文によって受け取ります。

これに対して、ジェネレーターイテレーター用いることで、指定したタイミングで戻り値を返し一旦終了。次に数を呼ぶと前回の続きからスタートし、再び戻り値を返してくれるものになってます。

メリット:例

関数の戻り値が、なんらかの計算の結果を格納した膨大なリストや辞書構造の場合、メモリ負荷につながります。結果をどこか、別サーバーのデータベースやファイルなどに格納するのであれば、各要素ごとにデータベースに登録しても、問題はないはずです。

この、各要素というのをジェネレーターイテレーターでもって取得することができます

ジェネレーター関数

関数内にyield式が入っている関数のことです。yield式とは、return 〇〇のように関数の戻り値を返すためのもの。

使い方

python2の場合

python3の場合、count.next()は、

になります。

2行目:ジェネレーターイテレーター

冒頭で述べた通り、ジェネレーター関数を用いて、ジェネレーターイテレーター(count)を用意します。

3~5行目:戻り値の取得

ジェネレーター関数内の待機地点の更新戻り値の取得を行います。

結果とタイミングについて

以下のように出力されます。

count.next()によって、返ってくる値、つまり、呼ばれるyield式が変わっているのがわかると思います。

タイミングについて、もう少し詳しく見ていくと

count.next()を1回にした場合、

と出力されました。

このことから、count.next()を呼ぶごとに次のyield式で待機することがわかります。

yieldの数 < next()の数 の場合エラー

次のyield式で待機することから、次のyield式がない場合 StopIteration というエラーが表示されます。今回であれば、yieldの数は3個なので、4回目のcount.next()を呼んでしまうとエラーになります。

一般的な使い方

前の使い方では、yield式を何回も差し込んでいる形なので、関数としての意味が薄いと思います。

for文を使うと意味合いが出ます。

結果は以下の通り、

9行目:for文によって、すべてのyieldを返す

これによって、いちいちyieldの数とnext()の数を気にする必要がありません。

最後に

本来は有用性について、もっと具体例を交えるべきですが、内容が広がるので仕方なく簡略して説明しました。有効な場面があるので、頭の片隅にでも置いてもらえれば、と思います。

参考

https://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09