[Tutor] recursive generator

Rich Lovely roadierich at googlemail.com
Sun Mar 7 17:46:28 CET 2010


On 7 March 2010 12:58, spir <denis.spir at gmail.com> wrote:
> Hello,
>
> Is it possible at all to have a recursive generator? I think at a iterator for a recursive data structure (here, a trie). The following code does not work: it only yields a single value. Like if child.__iter__() were never called.
>
>    def __iter__(self):
>        ''' Iteration on (key,value) pairs. '''
>        print '*',
>        if self.holdsEntry:
>            yield (self.key,self.value)
>        for child in self.children:
>            print "<",
>            child.__iter__()
>            print ">",
>        raise StopIteration
>
> With the debug prints in code above, "for e in t: print e" outputs:
>
> * ('', 0)
> < > < > < > < > < > < > < > < >
>
> print len(t.children) # --> 9
>
> Why is no child.__iter__() executed at all? I imagine this can be caused by the special feature of a generator recording current execution point. (But then, is it at all possible to have a call in a generator? Or does the issue only appear whan the callee is a generator itself?) Else, the must be an obvious error in my code.
>
>
> Denis
> --
> ________________________________
>
> la vita e estrany
>
> spir.wikidot.com
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>

You are calling child.__iter__(), but it's return value is being thrown away.

What you want to be doing is something like

    def __iter__(self):
        if self.holdsEntry:
            yield self.entry
        for child in self.children:
            print "<"
            for val in child: #implicit call to child.__iter__()
                yield val
            print ">"

Then, when the child.__iter__() is called, the returned iterator is
iterated, and the values are passed up the call stack.  There's
probably a more terse way of doing this using itertools, but I think
this is probably more readable.

Hope this clears things up (a little, anyway...)
-- 
Rich "Roadie Rich" Lovely

Just because you CAN do something, doesn't necessarily mean you SHOULD.
In fact, more often than not, you probably SHOULDN'T.  Especially if I
suggested it.

10 re-discover BASIC
20 ???
30 PRINT "Profit"
40 GOTO 10


More information about the Tutor mailing list