我正在练习yield
声明。我在Python 2.7中编写了以下函数:
>>> def mygen():
... i = 0
... j = 3
... for k in range(i, j):
... yield k
...
>>> mygen().next()
0
>>> mygen().next()
0
>>> mygen().next()
0
每当我致电mygen().next()
时,它始终会将输出显示为0
,而不是0
,1
,2
& StopIteration
。有人可以解释一下吗?
答案 0 :(得分:10)
每次重新创建生成器,因此每次都从头开始。
创建生成器一次:
gen = mygen()
gen.next()
gen.next()
gen.next()
每次调用它时,生成器函数都会生成一个新的迭代器;这样你就可以制作出多个独立的副本。每个独立的迭代器都是函数的调用,可以与其他函数分开执行:
>>> def mygen():
... i = 0
... j = 3
... for k in range(i, j):
... yield k
...
>>> gen1 = mygen()
>>> gen2 = mygen()
>>> gen1.next()
0
>>> gen1.next()
1
>>> gen2.next()
0
>>> gen2.next()
1
>>> gen1.next()
2
>>> gen1.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
请注意,您可能希望使用next()
function而不是直接调用generator.next()
:
next(gen)
generator.next()
被认为是一个钩子(Python 3将其重命名为generator.__next__()
,next()
函数是以交叉版本兼容的方式调用它的官方API。
答案 1 :(得分:0)
包含yield语句的函数定义返回一个生成器。您必须将下一个函数应用于该生成器而不是函数本身。为了澄清,您的函数定义等同于:
def mygen():
i, j = 0, 3
return (k for k in range(i, j))
或:
mygen = lambda :(k for k in range(0, 3))
所以你会这样使用它:
gen1 = mygen()
gen2 = mygen()
next(gen1) // returns 0
next(gen1) // returns 1
list(gen1) // returns [2]
list(gen2) // returns [0, 1, 2]