Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generator Expression vs yield: Why isn't 'next()' working?

Tags:

python

I know I must be missing something simple, but I am not seeing it.

If I have a generator expression like this:

>>> serializer=(sn for sn in xrange(0,sys.maxint))

I can generate, easily, individual integers like this:

>>> serializer.next()
0
>>> serializer.next()
1
>>> serializer.next()
2

If I write a generator like this:

>>> def ser():
...    for sn in xrange(0,100000):
...       yield sn

It is no bueno:

>>> ser().next()
0
>>> ser().next()
0
>>> ser().next()
0

??? What am I missing ???

like image 776
dawg Avatar asked Jun 09 '12 05:06

dawg


People also ask

What does next () do in a generator Python?

The next() function returns the next item in an iterator. You can add a default return value, to return if the iterable has reached to its end.

Can a generator function have multiple yield expressions?

If you want to return multiple values from a function, you can use generator functions with yield keywords. The yield expressions return multiple values. They return one value, then wait, save the local state, and resume again.

What does the yield statement in a generator do?

The yield keyword pauses generator function execution and the value of the expression following the yield keyword is returned to the generator's caller. It can be thought of as a generator-based version of the return keyword.

How many times Yield statement can be used in generator?

Unless your generator is infinite, you can iterate through it one time only. Once all values have been evaluated, iteration will stop and the for loop will exit. If you used next() , then instead you'll get an explicit StopIteration exception.


2 Answers

ser() creates the generator. So each time you call ser() it is sending you a new generator instance. You need to use it just like the expression:

serializer = ser()
serializer.next()

Consider that, if it didn't work this way, you could only ever use the ser() function once and you could never reset it. Plus, you can change the ser function to accept a max integer, and make your program more flexible.

def ser(n=sys.maxint):
    for sn in xrange(0, n):
        yield sn
like image 78
Jeff Tratner Avatar answered Sep 22 '22 19:09

Jeff Tratner


In your second example you keep creating a new instance, starting with a fresh generator.

g = ser()
g.next()
g.next()

Create the generator once and reuse it.

like image 27
jdi Avatar answered Sep 20 '22 19:09

jdi