recursive outline numbering for object trees
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Mon Mar 30 12:15:36 EDT 2009
Alia Khouri <alia_khouri <at> yahoo.com> writes:
> Given the following class:
>
> class Node(object):
> def __init__(self, name, children=[], parent=None):
> self.name = name
> self.level = ''
> self.children = children
> self.parent = parent
>
> def __repr__(self):
> name = self.__class__.__name__
> return "<%s %s>" % (self.name, self.level)
>
> def __iter__(self):
> yield self
> for child in self.children:
> child.parent = self
> for subchild in iter(child):
> yield subchild
>
> and the following example:
>
> tree1 = Node('root [1] ', [
> Node('branch [1.1]', [
> Node('leaf [1.1.1]', []),
> Node('leaf [1.1.2]', []),
>
> ]),
> Node('branch [1.2]', [
> Node('leaf [1.2.1]', []),
> Node('leaf [1.2.2]', []),
> ])
> ])
>
> I would like to create a walk function which when given the root node
> (tree1) automatically sets the correct outline numbering for all its
> subnodes.
>
> such that
>
> for i in walk(tree):
> print i.level
>
> should give the following output:
>
> 1
> 1.1
> 1.1.1
> 1.1.2
> 1.2
> 1.2.1
> 1.2.2
>
> Now, I have scoured the web and found this (http://
> www.opensubscriber.com/message/python-list <at> python.org/9056939.html)
> solution from castironpi, which seems to work nicely:
With a slight modification (don't automatically advance in up/down)
castironpi's code is easier to use in this case:
class up( Exception ): pass
class down( Exception ): pass
def outline():
stack = [1]
while True:
try:
# print 'next'
yield '.'.join(str(s) for s in stack)
stack[-1]+= 1
except down:
# print 'down'
stack.append(0)
except up:
# print 'up'
stack.pop(-1)
def walk(node, o=None):
if o is None:
o = outline()
node.level = o.next()
yield node
if node.children:
o.throw(down)
for child in node.children:
for subnode in walk(child, o):
yield subnode
o.throw(up)
(BTW, there is a proposal for a "yield from" statement, so the last part would
become:
o.throw(down)
for child in node.children:
yield from walk(child, o)
o.throw(up)
and I think it's a lot clearer)
> As an aside, if a solution is possible as an external walk function
> would it be possible to work in __iter__?
return walk(self)
--
Gabriel Genellina
More information about the Python-list
mailing list