So I have a generator function, that looks like this.
def generator(): while True: for x in range(3): for j in range(5): yield x
After I load up this function and call "next" a bunch of times, I'd expect it to yield values
0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 0 0 0 0 0 ...
But instead it just yields 0 all the time. Why is that?
>>> execfile("test.py") >>> generator <function generator at 0x10b6121b8> >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0 >>> generator().next() 0
Python generators are a simple way of creating iterators. All the work we mentioned above are automatically handled by generators in Python. Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).
You need to call next() or loop through the generator object to access the values produced by the generator expression. When there isn't the next value in the generator object, a StopIteration exception is thrown. A for loop can be used to iterate the generator object.
Generator Functions are memory efficient, as they save a lot of memory while using generators. A normal function will return a sequence of items, but before giving the result, it creates a sequence in memory and then gives us the result, whereas the generator function produces one output at a time.
This generator uses an iterator, because the "for" loop is implemented using an iterator. If you time these, the generator is consistently faster. Why is this, when the generator uses an iterator? Thanks.
generator()
initializes new generator object:
In [4]: generator() is generator() # Creating 2 separate objects Out[4]: False
Then generator().next()
gets the first value from the newly created generator object (0 in your case).
You should call generator
once:
In [5]: gen = generator() # Storing new generator object, will reuse it In [6]: [gen.next() for _ in range(6)] # Get first 6 values for demonstration purposes Out[6]: [0, 0, 0, 0, 0, 1]
Note: generator.next
was removed from Python 3 (PEP 3114) - use the next
function instead:
In [7]: next(gen) Out[7]: 1
With each call of generator
you are creating a new generator object:
generator().next() # 1st item in 1st generator generator().next() # 1st item in 2nd generator
Create one generator, and then call the next
for subsequent items:
g = generator() g.next() # 1st item in 1st generator g.next() # 2nd item in 1st generator
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