「列挙」組み込み関数と同様に動作するジェネレーターを構築することにより、yield ステートメントの動作を理解しようとしていますが、それを反復する方法によっては矛盾が発生します。
def enumerate(sequence, start=0):
n = start
for elem in sequence:
print("Before the 'yield' statement in the generator, n = {}".format(n))
yield n, elem
n += 1
print("After the 'yield' statement in the generator, n = {}".format(n))
ジェネレーターについての私の理解では、yield ステートメントに到達するとコードの実行が停止し、値が返されるということです。これは、以下のスクリプトで取得したものと一致します。
a = 'foo'
b = enumerate(a)
n1,v1 = next(b)
print('n1 = {}, v1 = {}\n'.format(n1,v1))
n2,v2 = next(b)
print('n2 = {}, v2 = {}'.format(n2,v2))
この場合、ジェネレーターは yield ステートメントで正確に停止したように見え、n+=1 ステートメントで 2 番目の 'next' ステートメントで再開します。
Before the 'yield' statement in the generator, n = 0
n1 = 0, v1 = f
After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n2 = 1, v2 = o
ただし、以下の for ループを使用すると、ジェネレーターは yield ステートメントで停止していないようです。
for n,v in enumerate(a[0:1]):
print('n = {}, v = {}'.format(n,v))
これは私が得るものです:
Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1
コメントを考慮して編集する
1 つの要素だけを繰り返し処理していることはわかっていますが、最後の「ジェネレーターの 'yield' ステートメントの後」という文 (すべての要素を繰り返し処理しても表示される) が表示されるとは思っていませんでした。
print('\n\n')
for n,v in enumerate(a):
print('n = {}, v = {}'.format(n,v))
Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n = 1, v = o
After the 'yield' statement in the generator, n = 2
Before the 'yield' statement in the generator, n = 2
n = 2, v = o
After the 'yield' statement in the generator, n = 3
なぜこれが起こるのですか?