Ответ 1
Генераторы (как и все повторяющиеся) могут быть только повторены один раз. По прошествии времени 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
даст больше значений.
Легче видеть, что генератор x
делится с y
, когда вы используете по ним функцию next()
:
>>> 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
Обратите внимание на StopIteration
, поднятый next(y)
, также здесь.