【ジェネレータとは】自作のジェネレータ関数で解説(Python)
Pythonにはジェネレータという機能があります。
ジェネレータ関数とは、Pythonにおいて反復可能なオブジェクトを生成するために使用される特殊な関数です。ジェネレータは、要素を一度に全てメモリに展開せずに、要素を必要な分だけ生成することができます。
一般的にはジェネレータはこのように説明しますが、これだけだとピンと来ません。
今回は自作したジェネレータ関数を動かして、どのような挙動をするか見ていただこうと思います。
自作したジェネレータ関数
def my_generator():
yield 1
yield 2
yield 3
ジェネレータ関数を自作するとこのようになります。
関数内にyieldと書くと、それはジェネレータ関数となります。
このジェネレータ関数からジェネレータオブジェクトを作ると、1回目は1を2回目は2を3回目は3を返します。
イメージとしてはreturnに近く、取り出す度に返り値が変わるreturnといったイメージです。
取り出し方法1
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator() # ジェネレータオブジェクトを生成
print(next(gen)) # 1が表示される
print(next(gen)) # 2が表示される
print(next(gen)) # 3が表示される
このジェネレータオブジェクトから値を取り出す方法は主に2つがあります。
1つはnext関数を使った方法です。
next(gen)とすると、呼び出す度に値が変わることが分かります。
取り出し方法2
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator() # ジェネレータオブジェクトを生成
for i in gen:
print(i) # 1-3が順番に表示される
もう1つはfor文を使った取り出し方です。
inの右側にジェネレータオブジェクトを書くと、リストなどと同じように順番に値を得ることができます。
ジェネレータ関数を使うメリット
先ほどのfor文の例を見たときに、じゃあジェネレータなど使わずリストで返せばいいじゃないかと思ったかもしれません。
ジェネレータを使うメリットは、リストと比較すると理解しやすくなります。
例えば[1, 2, 3]として返すとリストデータ全部のメモリを確保する必要があります。
それに対して、ジェネレータが1度に返す値は1つだけでメモリの量も1つ分だけです。
そのため、今回の例でいけば使用するメモリはリストの3分の1で済みます。
このように使用するメモリ量を節約できるのがジェネレータの特徴で、大規模なデータ受け渡しをする際にこのメリットが効いてきます。