Skip to content

4.8 ジェネレータ

ジェネレータは、Pythonのシーケンスを作成するオブジェクトです。 最大のメリットは、シーケンス全体を一度に作ってメモリに格納しなくても、巨大なシーケンスを反復処理できる点にあります。

リストなどのデータ構造はすべての要素をメモリ上に保持しますが、ジェネレータは反復処理のたびに**「その場で一度にひとつずつ」**値を作り出します。 ジェネレータは、最後に呼び出されたときに自分がどこにいたかを管理・記憶しており、次に呼び出されたときにはその続きから次の値を返します。

ジェネレータ関数の書き方(yield の活用)

Section titled “ジェネレータ関数の書き方(yield の活用)”

ジェネレータ内包表記(丸かっこを使った内包表記)に収まらないような複雑なシーケンスを作りたい場合は、「ジェネレータ関数」を書きます。

通常の関数とジェネレータ関数の違いはたった1つです。 値を返すときに return ではなく yield を使う、これだけです。

独自の range() 関数を作ってみる

Section titled “独自の range() 関数を作ってみる”

例として、標準の range() と似た働きをするジェネレータ関数 my_range を自作してみましょう。

# ジェネレータ関数の定義
def my_range(first=0, last=10, step=1):
number = first
while number < last:
yield number # returnの代わりにyieldを使う
number += step # 次の呼び出しに向けて値を更新する
# 関数自体は通常の関数です
print(type(my_range)) # <class 'function'>

ジェネレータ関数を呼び出すと、値そのものではなく「ジェネレータオブジェクト」が返されます。これを for ループなどで反復処理します。

# ジェネレータオブジェクトの作成
ranger = my_range(1, 5)
print(type(ranger)) # <class 'generator'>
# forループで反復処理(1つずつ値が生成される)
for x in ranger:
print(x)
# 出力:
# 1
# 2
# 3
# 4