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.
Python doesn't have any support for cloning generators.
A Python generator is a function that produces a sequence of results. It works by maintaining its local state, so that the function can resume again exactly where it left off when called subsequent times. Thus, you can think of a generator as something like a powerful iterator.
from types import GeneratorType;type(myobject, GeneratorType) will give you the proper result for objects of class 'generator'.
Generators are memory efficient since they only require memory for the one value they yield. Generators are lazy: they only yield values when explicitly asked.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With