Reputation: 861
I've created a general tree in python, by creating a Node object. Each node can have either 0, 1, or 2 trees.
I'm trying to create a method to print a list of all the nodes in a tree. The list need not be in order. Here's my simplistic attempt:
def allChildren(self, l = list()):
l.append(self)
for child in self.children:
l = child.allChildren(l)
return l
The first time I run this method, it works correctly. However, for some reason it is storing the previous runs. The second time I run the method, it prints all the nodes twice. Even if I create 2 separate trees, it still remembers the previous runs. E.g: I create 2 trees, a and b. If I run a.allChildren() I receive the correct result. Then I run b.allChildren() and recieve all of a's nodes and all of b's nodes.
Upvotes: 1
Views: 855
Reputation: 117370
If you're writing default parameter like l = list(), it will create list when compiling function, so it will one instance of list for all function calls. To prevent this, use None and create new list inside the function:
def allChildren(self, l = None):
if not l: l = []
l.append(self)
for child in self.children:
l = child.allChildren(l)
return l
Upvotes: 2
Reputation: 20267
You have a mutable value as the default value of your function parameter l
. In Python, this means that when you call l.append(self)
, you are permanently modifying the default parameter.
In order to avoid this problem, set l
to a new list every time the function is called, if no list is passed in:
def allChildren(self, l = None):
if l is None:
l = list()
l.append(self)
for child in self.children:
l = child.allChildren(l)
return l
This phenomenon is explained much more thoroughly in this question.
Upvotes: 5
Reputation: 5289
try this:
def allChildren(self, l = None):
if(l==None):
l = list()
l.append(self)
for child in self.children:
l = child.allChildren(l)
return l
And check out this answer for explanation.
Upvotes: 3