26

I am new to generator in python. I have a simple enough code which I am playing with but I can not understand the output I am getting out of it. Here is my code :

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)

I expected my output to be like this :

0  1  2 
1  2  3

But I am seeing only : 0 1 2

I do not understand this output. Can anyone please help me sort out my lack of understanding? Thanks in advance.

1
  • your generator is exhausted when you reach the last line.
    – njzk2
    Commented Apr 23, 2014 at 16:17

1 Answer 1

7

Generators (like all iterables) can only be iterated over once. By the time print_gen(x) is done, so is x. Any further attempts to get new values from x will result in StopIteration being raised.

This works:

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

as that creates two separate independent generators. In your version, the generator expression you assigned to y expects x to yield more values.

It is easier to see that the x generator is shared with y when you use the next() function on them in turn:

>>> 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

Note the StopIteration raised by next(y) as well here.

2
  • Or rather: generators return an iterator, which is the thing that can only be iterated over once. Commented Apr 23, 2014 at 16:16
  • 1
    @AlexThornton: generally speaking, generators are a specialized iterator. Commented Apr 23, 2014 at 16:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.