[Tutor] How to find descendants recursively?

Dave Angel davea at davea.name
Mon Jun 17 01:21:36 CEST 2013


On 06/16/2013 01:20 PM, Timo wrote:
> I have a datafile which is parsed by an external library, I'm having
> trouble creating a hierarchical structure of the data.
>
> This is what I got so far:
>
> items = get_items() # returns a generator
> for item in items:
>      print(item)
>      children = get_children(item) # also returns a generator
>      for child in children:
>          print("--", child)
>
> This is fine as it will get the children for each parent item. I can't seem
> to figure out how to go further and get the chidren of the children and so
> on.
>
I can't see any way of doing recursion without writing a function.  You 
can always fake it, but if you want the language's help, do it in a 
function.

We don't know your external library.  But if the effect is to produce a 
tree, where any node may have items as children, then recursion is the 
easiest way to process the whole tree.  Some assumptions are important:

The tree has reasonable max-depth, like less than 1000.  If it's 
somewhat larger, but has a known limit, you can probably just get away 
with telling Python to use a larger stacksize.  But if the depth could 
be arbitrarily large, say a million levels, then you need another 
approach than the language's recursion.

Second assumption is that no node appears more than once in the tree. 
For example, in a Unix directory tree, if a symlink points back up the 
tree, it can cause troubles.  Avoiding these troubles is not hard if you 
plan ahead, but it's easier if you know it cannot happen.

Assuming the tree is well-enough behaved then, we want to define a 
function, with a name, that will call itself.  Each time you descend 
into a  child node, you call the function recursively to process that 
childlist.

Now, eventually you'll probably want to make this recursive function a 
generator, so you can reuse it for other tree processing of the same 
kind of tree.  But that can wait.

First you have to decide how you can test the limit-condition.  For 
example, perhaps your unknown library returns Null from  the 
get_children() call if there are no children.  Or perhaps there's 
another call, like has_children() which returns a bool.  Without knowing 
that, it's hard to structure the rest of the function.  But roughly it 
looks like:

after the children= line, simply test your condition and call yourself 
with children as the argument.

     children = get_children(item)
     if children not is None:
         my_recursive_function(children)

You don't need or want to write a loop for child in children, since that 
same loop is already written (if item in items).



You pick your own better name for the function, based on what it does.

-- 
DaveA


More information about the Tutor mailing list