理解Python生成器的困难

26

我对Python中的生成器很陌生。我有一个非常简单的代码,但我无法理解它输出的结果。以下是我的代码:

def do_gen():
    for i in range(3):
        yield i

def incr_gen(y):
    return y + 1

def print_gen(x):
    for i in x:
        print i

x = do_gen()
y = (incr_gen(i) for i in x)
print_gen(x)
print_gen(y)

我期望我的输出结果应该是这样的:

0  1  2 
1  2  3

但我只看到:

0 1 2

我不理解这个输出。是否有人能帮我弄清楚我的理解不足呢?提前感谢。


当你到达最后一行时,你的生成器已经耗尽。 - njzk2
1个回答

7

生成器(像所有可迭代对象一样)只能被迭代一次。当print_gen(x)完成时,x也完成了。任何后续尝试从x获取新值都将导致引发StopIteration异常。

这是有效的:

x = do_gen()
y = (incr_gen(i) for i in do_gen())
print_gen(x)
print_gen(y)

这会创建两个独立的生成器。在你的版本中,你为y分配的生成器表达式期望x产生更多的值。

当你依次使用next()函数对它们进行操作,更容易看出x生成器与y共享:

>>> def do_gen():
...     for i in range(3):
...         yield i
... 
>>> def incr_gen(y):
...     return y + 1
... 
>>> x = do_gen()
>>> y = (incr_gen(i) for i in x)
>>> next(x)  # first value for the range
0
>>> next(y)  # second value from the range, plus 1
2
>>> next(x)  # third value from the range
2
>>> next(y)  # no more values available, generator done
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

请注意这里由next(y)引发的StopIteration

或者说:生成器返回一个迭代器,这个迭代器只能被迭代一次。 - anon582847382
1
@AlexThornton:一般来说,生成器是一种特殊的迭代器。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接