在生成器函数上使用 next()

问题描述 投票:0回答:3

我有这个生成器函数:-

def gen():
    for i in range(3):
        yield i*i

现在,当我在

next()
上调用
gen()
时,它每次都给出第一个元素。

>>> next(gen())
0
>>> next(gen())
0

但是当我在

for
循环中使用它时,它按预期工作:

>>> for i in gen():
...     print(i)
... 
0
1
4

有人可以解释这种效果的原因以及我在这里缺少的概念吗?

python python-3.x generator next
3个回答
10
投票

每次调用

gen()
.

时,您的函数都会返回一个新的生成器

我认为最简单的理解方法是对比你在做什么:

>>> next(gen())
0
>>> next(gen())
0

这个:

>>> my_gen = gen()
>>> next(my_gen)
0
>>> next(my_gen)
1
>>> next(my_gen)
4
>>> next(my_gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

在后一种情况下,我从 same 生成器中获取新值。


5
投票

每次调用该函数时,它都会返回一个生成器对象。每次你调用 next 时,你都会得到第一个项目,即

0 * 0
因为你不是在同一个对象上调用 next(每次都是新的)。但在第二种情况下,你循环遍历一个生成器对象,它会继续消耗生成器,直到它到达
StopIteration
.

为了更好的演示,您可以从生成器函数创建两个迭代器对象并同时循环它们:

In [17]: g = gen()

In [18]: k = gen()

In [19]: for i, j in zip(g, k):
    ...:     print(i, j)
    ...:     
0 0
1 1
4 4

1
投票
days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
def gen(d):
    for i in d: 
        yield i 

obj = gen(days)

print(next(obj, 'Default Value')) # 'Sun'
print(next(obj, 'Default Value')) # 'Mon'

print('oooooooooooooooooooooooooooooooooooooooo')    

for j in obj:
    print(j)  # 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'

 
print(next(obj, 'Default Value')) # Default Value
  • 在上面我们已经调用了 next() 两次所以我们知道生成器函数保存程序执行的状态所以在 for 循环中它返回 来自下一个生成器对象的对象

  • 但是如果我们首先使用

    for loop
    然后在 for 循环中我们接收或调用所有生成的对象,所以我们没有任何生成器对象,所以我们将获得
    next()
    函数调用的默认值

输出:

Sun
Mon
oooooooooooooooooooooooooooooooooooooooo
Tue
Wed
Thu
Fri
Sat
Default Value
© www.soinside.com 2019 - 2024. All rights reserved.