我正在尝试通过构建一个类似于“enumerate”内置函数的生成器来理解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语句处停止,并在第二个“next”语句中的n+=1处恢复:
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
考虑评论后进行编辑
我意识到我只迭代了一个元素,但我没有预料到即使我迭代所有元素,也会看到最后一个“在生成器的'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
为什么会发生这种情况?
print(a[0:1])
。 - Mad Physicistfor
循环在产生第一个值后就停止了,那它就不是一个循环了,对吧?这个循环会一直持续到没有剩余的值为止。 - Aran-Fey