Reputation: 119
Is there a better was to print a tree? I am doing the following. I am building a tree with the following code. What mistake am I really doing? it is giving the following error
63 ret = "\t"*level+repr(self.label)+"\n"
64 for child in self.children:
---> 65 ret += child.__str__(level+1)
66 return ret
67
TypeError: expected 0 arguments, got 1
Code attached below
from collections import Counter
from sets import Set
class treenode:
def __init__(self, values):
self.label = values
self.children = {}
def __str__(self, level=0):
ret = "\t"*level+repr(self.label)+"\n"
for child in self.children:
ret += child.__str__(level+1)
return ret
def __repr__(self):
return '<tree node representation>'
def build_tree(featurerange, featureid, counts):
if len(sorted(counts)) > 1:
featuresLeft = featurerange - Set([featureid])
if not featuresLeft:
rootnode.children[v] = treenode(counts.most_common(1)[0][0])
else:
rootnode.children[v] = build_tree(featuresLeft)
else:
rootnode.children[v] = treenode(counts.most_common(1)[0][0])
return rootnode
featurerange = set([0, 1])
featureid = 1
counts = Counter({'-': 49, '+': 45})
tree = build_tree(featurerange, featureid, counts)
str(tree)
print tree
Upvotes: 2
Views: 526
Reputation: 1121584
You are setting children
to default to an empty dictionary:
def __init__(self, values, children = {}):
shared between instances. You then proceed to replace the same key over and over again with:
rootnode.children[v] = treenode(counts.most_common(1)[0][0])
where v
is a global; you haven't shared it in your question, so I don't know what kind of object that is.
Looping over self.children
then loops over the keys of the dictionary:
for child in self.children:
child
is then not a treenode
instance, so the __str__
method doesn't take extra arguments. It is instead that one v
value, but it clearly does not implement a object.__str__
method that takes extra arguments.
Perhaps you wanted to make children
a list instead? In any case, there are several issues in your code that you need to address:
You are using a mutable default argument here, you are creating one dictionary and all your instances share it. See "Least Astonishment" and the Mutable Default Argument for why you want to avoid that. Use:
def __init__(self, values, children=None):
if children is None:
children = {}
You appear to be using a v
global in build_tree()
; did you really need to use a dictionary and one key in that dictionary? Shouldn't children
be a sequence or collection instead? If so, use list.append()
or set.add()
grow the collection of children.
You appear to be using the deprecated sets.Set()
object; use the built-in set()
type instead.
The approach itself, provided you actually loop over a collection of treenode
objects, works just fine. You could loop over the values of the dictionary, perhaps:
for child in self.children.values():
Upvotes: 2