树构建器和层次结构中的打印节点

时间:2015-02-04 09:29:02

标签: python tree

印刷树是否更好?我正在做以下事情。我正在使用以下代码构建一棵树。我到底犯了什么错误?它给出了以下错误

      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 

下面的代码

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

1 个答案:

答案 0 :(得分:2)

您将children设置为默认为空字典:

def __init__(self, values, children = {}):

在实例之间共享。然后使用以下方法一遍又一遍地替换相同的密钥

rootnode.children[v] = treenode(counts.most_common(1)[0][0])

其中v是全球性的;你还没有在你的问题中分享它,所以我不知道那是什么类型的对象。

循环遍历self.children然后循环遍历字典的

for child in self.children:

child然后一个treenode实例,因此__str__方法不会带来额外的参数。相反,它只有一个v值,但它显然没有实现一个带有额外参数的object.__str__方法。

也许您想让children成为一个列表?无论如何,您需要解决代码中的几个问题:

  • 您在这里使用了一个可变的默认参数,您正在创建一个字典,并且所有实例都共享它。请参阅"Least Astonishment" and the Mutable Default Argument了解您为何要避免这种情况。使用:

    def __init__(self, values, children=None):
        if children is None:
            children = {}
    
  • 您似乎在v中使用build_tree()全局;你真的需要在字典中使用字典和一个键吗?不应该children是序列或集合吗?如果是这样,请使用list.append()set.add()增加子集合。

  • 您似乎正在使用deprecated sets.Set() object;请改用built-in set() type

方法本身,如果您实际循环遍历treenode个对象的集合,则可以正常工作。您可以循环遍历字典的值,可能是:

for child in self.children.values():