Mixing generators and recursion
Francis Avila
francisgavila at yahoo.com
Tue Nov 4 17:01:44 EST 2003
"Gerson Kurz" <gerson.kurz at t-online.de> wrote in message
news:3fa80eaa.22505703 at news.t-online.de...
> No, it has nothing to do with the pathname. Try this:
>
> def f(nested):
> if not nested:
> f(True)
> else:
> yield 42
>
> for k in f(False): print k
>
> Step through it in the mind:
> - f(False) gets called
> - it is not nested, so f(True) gets called
> - it is nested, so should yield 42 - but it doesn't!
> - instead, you get an empty list.
Computer's can't read our minds, though....
> def f(nested):
> if not nested:
F is false so...
> f(True)
...call function f(True), which returns a *generator*...
...which is never bound to anything, so the refcount goes to 0.
> else:
> yield 42
Above never gets executed by anything at all.
Look:
>>> def g():
... yield 'Hello there!'
...
>>> type(g)
<type 'function'>
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
g.next()
AttributeError: 'function' object has no attribute 'next'
>>> G = g()
>>> type(G)
<type 'generator'>
>>> G.next()
'Hello there!'
>>>
See the difference?
What you want something like:
def f(nested):
if not nested:
for v in f(True): yield v
else:
yield 42
for k in f(False): print k # 42
I.e., you must explicitly iterate the generator. No 'yield' ever yields
without a next() asking first. (That next() call can be implicit or
explicit, but it's still always there.)
--
Francis Avila
More information about the Python-list
mailing list