Python ジェネレータ(generator)

目次

(確認環境:Python 3)

ジェネレータ(generator)とは

  • イテレーション(繰り返し処理)に特化した「特殊なイテレータ」のことです。
  • 必要なときに必要なデータを順次生成する仕組みで、大量データや無限列に便利です。
  • 関数内にキーワードのyieldを記述します。
  • yield文は値を返します。
  • 関数を呼ぶ側は、next関数で呼び出します。
  • send関数を使用すると関数に値をセットすることができます。

ジェネレータのサンプルです。

def test1():
    yield "a"
    yield "b"
    yield "c"

t1 = test1()  # ジェネレータの作成

print(next(t1))  # a
print(next(t1))  # b
print(next(t1))  # c
print(next(t1))  # StopIteration

1~4行目は、関数です。
6行目は、ジェネレータを作成しています。
8~10行目は、next関数でtest1関数の値が順に表示されます。

11行目は、実行するコードが残っていないのでStopIterationがでます。

StopIterationは例外クラスですが、意味は終了通知です。

while文を使用したサンプル

def test1(a):
    while a < 3:
        yield a
        a += 1

t1 = test1(0)  # ジェネレータの作成

print(next(t1))  # 0
print(next(t1))  # 1
print(next(t1))  # 2
print(next(t1))  # StopIteration

1~4行目は、関数です。

while a < 3により、最大3回ループします。

next()を呼ぶごとに1回ループします。

4回目のnext()で、実行するコードが残っていないのでStopIterationがでます。

StopIterationは例外クラスですが、意味は終了通知です。

ジェネレータ+send()の双方向通信の例

def test1(x):
	for a in range(10):
		b = yield ('Hello',x)
		if b is not None:
			x = b

t1 = test1("おはよう")   # ジェネレータの作成

print(next(t1)) # ('Hello','おはよう') # 最初の実行

t1.send("こんにちは") # yieldの式に値を渡す

print(next(t1)) # ('Hello','こんにちは')
print(next(t1)) # ('Hello','こんにちは')

4行目は、send関数のときにtrueになり5行目が実行されます。
9行目は、7行目の引数の値がセットされて表示されます。
11行目は、send関数です。引数の値を関数に渡します。
13,14行目は、13行目のsend関数でセットした値が表示されます。

yieldとreturnの違い

目的 再開 戻り回数
yield 一時停止して値を返す できる 複数回
return 関数を終了して値を返す できない 1回

関連の記事

Python ジェネレータとジェネレータ式の違い
Python リストとジェネレータ式とリスト内包表記の違い

△上に戻る