Generator question

Peter Otten __peter__ at web.de
Mon Nov 27 04:48:16 EST 2006


Mathias Panzenboeck wrote:

> Robert Kern wrote:
>> Timothy Wu wrote:
>>> Hi,
>>>
>>> Using generator recursively is not doing what I expect:
>>>
>>> def test_gen(x):
>>>     yield x
>>>     x = x - 1
>>>     if x != 0:
>>>         test_gen(x)
>> 
>> The only thing that the last line does is *create* a new generator
>> object. You need to actually iterate over it and yield its values. E.g.
>> 
>> 
>> In [2]: def test_gen(x):
>>    ...:     yield x
>>    ...:     x -= 1
>>    ...:     if x != 0:
>>    ...:         for y in test_gen(x):
>>    ...:             yield y
>>    ...:
>>    ...:
>> 
>> In [3]: list(test_gen(3))
>> Out[3]: [3, 2, 1]
>> 
>> 
> 
> why not this?

Because it doesn't answer the OP's question about recursive generators?
 
> def test_gen(x):
>     for y in xrange(x,0,-1):
>         yield y
> 
> or even better/shorter:
> 
> test_gen = lambda x: xrange(x,0,-1)

That's not a generator:

>>> g = test_gen(2)
>>> g.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'xrange' object has no attribute 'next'
>>> list(g)
[2, 1]
>>> list(g)
[2, 1]

This is:

>>> g = iter(xrange(2, 0, -1))
>>> g.next()
2
>>> list(g)
[1]
>>> list(g)
[]

Unless you are using it in a single for loop, the difference is not so
subtle...

Peter



More information about the Python-list mailing list