My Generator Paradox!

David Wahler dwahler at gmail.com
Fri Mar 17 01:34:24 CET 2006


vbgunz wrote:
> I am afraid that this is the first time in which I would probably need
> something explained to me as if I were a little child. I am having a
> hard time getting this through my thick skull. What in the world is
> wrong with this!?
>
> ''' ########################################################### '''
>
> def generatorFunction(sequence=['item1', 'item2', 'item3']):
>     for item in sequence:
>         yield item
>
> yieldedValue = generatorFunction()
>
> '''this seems to work perfectly.'''
> print '-' * 32
> print yieldedValue          # <generator object at 0xb723014c>
> print yieldedValue.next()   # item1
> print yieldedValue.next()   # item2
> print yieldedValue.next()   # item3
>
> '''this is where things don't make any sense!'''
> print '-' * 32
> print generatorFunction()           # <generator object at 0xb723022c>
> print generatorFunction().next()    # item1
> print generatorFunction().next()    # item1
> print generatorFunction().next()    # item1
>
> ''' ########################################################### '''
>
> the first set of calls assigned to yieldedValue work but the second set
> without assignment don't.  I asked for help on this at #python (I love
> those people in there!) and was told the following...
> generatorFunction() is a call (obvious) when calling the second set, I
> am resetting the iteration and this explains why I only and always get
> item1.
>
> ok. *but* why in the world does the first set of calls work?
> technically, isn't yieldedValue == generatorFunction() on a name basis?
> I mean isn't the following technically the same?
>
> generatorFunction()
> yieldedValue = generatorFunction()
>
> aren't they both the same?
[snip]

In that short example, they happen to be different, but equivalent,
objects, but that will not always be the case. Consider this:

>>> a = generatorFunction()
>>> b = generatorFunction()
>>> print a.next()
item1

Now a and b are both generators for generatorFunction, but calling
a.next() again will return 'item2', while calling b.next() will return
'item1'. The value returned by generatorFunction is an object, which
has an internal state that makes it distinct from other objects of the
same type. So once your yieldedValue has been altered by calling the
next() method, it is no longer equivalent to a fresh instance of the
generator.

-- David




More information about the Python-list mailing list