bob.sacamento
bob.sacamento

Reputation: 6651

Passing a function through a linked list of objects

I have a class that creates a multiply linked list. Each node can have several (or one or no) children. The node has a pointer to its latest child node, and each child node has a pointer to it previous sibling. So I can walk the entire tree by taking each latest child, and then each of its siblings, in turn. This function walks the three successfully, but doesn't do anything useful:

def walk_the_tree(self):
    if not self.latestChild is None:
        self.latestChild.walk_the_tree()
    if not self.sib is None:
        self.sib.walk_the_tree()

Now, what I really want to do is to pass some kind of argument so that a member function can be executed at each node. Here's something that won't compile, but I hope it gets as what I am wanting:

def walk_the_tree(self, fcn):
    self.fcn()
    if not self.latestChild is None:
        self.latestChild.walk_the_tree()
    if not self.sib is None:
        self.sib.walk_the_tree()

So, fcn could be, for instance, just the class __repr__, so I can get all info on all the nodes quickly. Or it might be create_new_child() which would determine whether the node needs a new child and, if so, create it. I would like the user to be able to pick this without relying on some kind of flag. For instance, what I don't want is something like:

def walk_the_tree(self, fcnflg):
    if (fcnflg == 1): self.__repr__()
    if (fcnflg == 2): self.create_new_child()
    if not self.latestChild is None:
        self.latestChild.walk_the_tree()
    if not self.sib is None:
        self.sib.walk_the_tree()

Any way to do this?

Upvotes: 0

Views: 656

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96172

The problem is that you are using self.fcn but that isn't defined. Just use fcn. Here is a contrived example:

>>> class MyContainer(object):
...     def __init__(self, iterable=None):
...         if iterable is not None:
...             self.data = list(iterable)
...         else:
...             self.data = []
...     def walk_container(self, f):
...         for x in self.data:
...             print(f(x))
...     def _increment(self, x):
...         return x + 1
...     def print_increments(self):
...         self.walk_container(self._increment)
...
>>> c = MyContainer([0,1,2])
>>> c.print_increments()
1
2
3
>>>

Or if you want, use non-methods externally:

>>> c.walk_container(lambda x: x**2)
0
1
4
>>>

Upvotes: 1

Related Questions