5

「列挙」組み込み関数と同様に動作するジェネレーターを構築することにより、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

なぜこれが起こるのですか?

4

2 に答える 2