unbalanced tree iteration issue
kost BebiX
k.bx at ya.ru
Fri Jan 14 13:08:42 EST 2011
14.01.2011, 18:57, "Alex Boyko" <alex.kyrish at gmail.com>:
> 2011/1/14 kost BebiX <k.bx at ya.ru>
>> 14.01.2011, 14:15, "Alex Boyko" <alex.kyrish at gmail.com>:
>>
>>> Dear All!
>>>
>>> I have deal with large unbalanced trees and I have to implement post-order tree traversal. My first attempt is shown below ("Node" and "Tree" classes) and based on recursive generators approach.
>>>
>>> class Node():
>>> def __init__(self,value):
>>> self.childs = []
>>> self.value = value
>>>
>>> class Tree():
>>>
>>> def __init__(self, root):
>>> self.root = root
>>> self.numberCells = 1
>>>
>>> def add(self, node, child):
>>> node.childs.append(child)
>>> self.numberCells+=1
>>>
>>> def __iter__(self):
>>> return self.postorder(self.root)
>>>
>>> def postorder(self, node):
>>> if node:
>>> for child in node.childs:
>>> for n in self.postorder(child):
>>> yield n
>>> yield node
>>>
>>> It works fine for small test trees. But, my tree has approximately 300000 nodes, and shown post order traversal with generators takes 80 sec against 1 sec with simple recursive routine:
>>>
>>> def recursiveFromTop(node):
>>> for child in node.childs:
>>> recursiveFromTop(child)
>>> ## here I can do some computations with current node's data
>>>
>>> So, I'd like to know how should I implement (if it's possible of course) __iter__ for my tree class based on recursion without generators? Please, can You show me the ways?
>>> because I'm very passionate in idea iterate through my tree with simple:
>>>
>>> for node in tree:
>>> do something with node
>>>
>>> Thanks in Advance!
>>> Best Regards!
>>> Alex
>>>
>>
>>> --
>>> http://mail.python.org/mailman/listinfo/python-list
>>
>> Well, I think it's actually because the difference is that you would not do yielding, you would just put everything in memory and then return it.
>>
>> ret_val = [x for x in self.postorder(child)]
>> return ret_val + [self]
>>
>> or something like that (but beware of memory). But that's strange. This code works fast:
>>
>> #!/usr/bin/env python
>> # -*- coding: utf-8 -*-
>>
>> import sys
>>
>> def w(s):
>> sys.stdout.write("%s" % s)
>> sys.stdout.flush()
>>
>> class Node():
>> __slots__ = ('childs', 'value',)
>>
>> def __init__(self, value):
>> self.childs = []
>> self.value = value
>>
>> def post_order(self):
>> for child in self.childs:
>> yield child
>> yield self
>>
>> def build_tree():
>> def append_1000_childs(node):
>> for i in xrange(20):
>> node.childs.append(Node(10))
>>
>> def append_n_levels(node, levels=1):
>> if levels >= 1:
>> append_1000_childs(node)
>> if levels > 1:
>> for child in node.childs:
>>
>> append_n_levels(child, levels - 1)
>>
>> root = Node(10)
>> append_n_levels(root, 5)
>> return root
>>
>> if __name__ == '__main__':
>> from datetime import datetime
>>
>> w("building tree...")
>> _t = datetime.now()
>> root = build_tree()
>> w("done\n")
>> w(datetime.now() - _t)
>> w("\n")
>>
>> w("doing generator post_order...")
>> _t = datetime.now()
>> for item in root.post_order():
>> fake = item.value
>> w("done\n")
>> w(datetime.now() - _t)
>> w("\n")
>>
>> def post_order(root):
>> for child in root.childs:
>> post_order(child)
>> fake = item.value
>>
>> w("doing non-generator post_order...")
>> _t = datetime.now()
>> post_order(root)
>> w("done\n")
>> w(datetime.now() - _t)
>> w("\n")
>>
>> $ python postorder.py
>> building tree...done
>> 0:01:34.422288
>> doing generator post_order...done
>> 0:00:00.000018
>> doing non-generator post_order...done
>> 0:00:01.232272
>>
>> --
>> jabber: k.bx at ya.ru
> Thank you for your reply, but I have question about your code. Your defined:
>
> def post_order(self):
> for child in self.childs:
> yield child
> yield self
>
> just for "Node" , not for "Tree", and do
>
> w("doing generator post_order...")
> _t = datetime.now()
> for item in root.post_order():
> fake = item.value
> w("done\n")
> w(datetime.now() - _t)
> w("\n")
>
> what give us only iterating along root's children, not iterating along tree...Or I didn't catch your though?
>
> Best Regards
> Alex
>
Well, isn't tree is a root node and it's children? Why do you need Tree class anyway?
p.s.: please, do not top-post the messages, write your reply at bottom because it will then be easier to read for those who will google this page.
--
jabber: k.bx at ya.ru
More information about the Python-list
mailing list