[Tutor] not understanding a recursion example

Bill Allen wallenpb at gmail.com
Fri Jan 21 16:15:09 CET 2011


Peter,

Thank you very much for the explanation.   I understand this much better
now.   You are correct, the implementation you show is easier for me to
understand.



--Bill









On Fri, Jan 21, 2011 at 03:43, Peter Otten <__peter__ at web.de> wrote:

> Bill Allen wrote:
>
> > I am not understanding the following code (I did not write it).  It
> > demonstrates walking a tree-like data structure using recursion.  It does
> > run and produces reasonable output.  I particularly do not understand the
> > "traverse.level" statements.  Can anyone give me an idea how this is
> > working
> > and the principles?  I would like understand recursive calls in Python
> > better as I have not used the technique previously.
>
> > def traverse(data):
> >     print(' ' * traverse.level + data['text'])
> >     for kid in data['kids']:
> >         traverse.level += 1
> >         traverse(kid)
> >         traverse.level -= 1
> >
> > if __name__ == '__main__':
> >     traverse.level = 1
> >     traverse(data)
>
>
> Functions are objects in python; you can tuck arbitrary attributes onto
> them, and the above uses a function attribute instead of a global variable.
> A more standard way to write the above would be
>
> def traverse(data):
>    global level
>    print(' ' * level + data['text'])
>     for kid in data['kids']:
>         level += 1
>        traverse(kid)
>         level -= 1
>
> if __name__ == '__main__':
>     level = 1
>    traverse(data)
>
> What it does:
> * call traverse with the outermost dictionary
> * print the data["text"] value indented by the current global level.
> * iterate over the data["kids"] list of dictionaries
> * for each entry in that list
>    - increment indentation level
>    - invoke traverse which will print the data["text"] value.
>      (Remember that traverse was called with the current value of kid, so
>       in terms of the outer traverse() the inner traverse() is printing
>       kid["text"]) Process the kid's kids in the same way.
>    - decrement the indentation level
>
> However using global variables is generally a bad practice.
> It is easy to leave them in an inconsistent state, and if you are using
> multiple threads (i. e. invoke traverse() a second time while the first
> call
> hasn't finished) you'll end up with a big mess.
>
> I would therefore write the traverse function as
>
> def traverse(data, level):
>    print(' ' * level + data['text'])
>     for kid in data['kids']:
>         traverse(kid, level+1)
>
> if __name__ == "__main__":
>    traverse(data, 1)
>
> which I think may also be easier to understand.
>
> Peter
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110121/69022531/attachment.html>


More information about the Tutor mailing list