yieldを使ったジェネレータ
Pythonにはジェネレータを簡単に作るためのyieldという命令が有ります。
あまり挙動を理解できていなかったので、下記にメモを残します。
基本動作
test.py
def yield_test():
list0to4 = [0, 1, 2, 3, 4]
for i in list0to4:
yield i
for j in yield_test()
print j
上のコードを走らせると、出力は下記となります。
0
1
2
3
4
[0, 1, 2, 3, 4]の要素が順番に全て読み出せています。
ジェネレータを組み合わせる
ここで、別のジェネレータを組み合わせて使う場合を考えます。
test.py
def yield_test1():
list0to4 = [0, 1, 2, 3, 4]
for i in list0to4:
yield i
def yield_test2():
list0to2 = [0, 1, 2]
for i in list0to2:
yield i
iter0to2 = yield_test2()
for j in yield_test1()
print j + iter0to2.next()
この場合、出力は下記となります。
0
2
4
yield_test1よりもyield_test2の方が要素数が少ないですが、特にエラーも出ません。
ジェネレータの動作
ジェネレータは次の要素が無い状態で、次を読み込みにいくと例外[StopIteration]をraiseします。
for文などでは、この[StopIteration]をexceptしてループを止めているようです。
そのため、上の例ではiter0to2.next()で[StopIteration]がraiseされるため、
yield_test1()側に要素が残っていてもfor文を抜けてしまいます。
ジェネレータを組み合わせて使う場合は、どちらが原因でループを抜けたのか
分かり辛い場合があるので注意が必要です。