【问题标题】:recursively editing member variable: All instances have same value递归编辑成员变量:所有实例具有相同的值
【发布时间】:2015-06-08 14:17:37
【问题描述】:

我想创建一个由 TreeNode 对象组成的 Tree 数据结构。根是一个TreeNode。每个 TreeNode 都有一个父 TreeNode 和一个子 TreeNode 列表。 树是递归构建的。我简化了代码以使示例不太难。函数get_list_of_values_from_somewhere 工作正常。当 TreeNode 没有 child_values 并且 get_list_of_values_from_somewhere 返回一个空列表时,递归结束。效果很好。

每个 TreeNode 的子成员都不正确。该脚本将所有 TreeNode 收集到一个列表 (node_list) 中。在那里我可以检查每个TreeNode都有一个父节点,并且这个父节点是正确的。

但由于某种原因,他们都有相同的孩子名单。我不明白为什么。其他一切都是正确的。递归有效,TreeNode 被正确创建,它们的父节点是正确的。为什么他们的子列表没有正确填写?在创建实例之后如何编辑实例的 memver 变量?

class Tree(object):

    def __init__(self, root_value):
        print ("Creating tree")
        self.root = self.createTree(root_value)
        self.node_list = []

    def createTree(self, value, parent=None):
        node = TreeNode(value, parent)

        children_values = get_list_of_values_from_somewhere()
        for child_value in children_values:
            child_node = self.createTree(child_value, node)
            self.node_list.append(child_node)

            node.children.append(child_node)
            # I also tried alternatives:
            #node.insertChildren(self.createTree(child_value, node))
            #node.insertChild(child_node)

        return node


class TreeNode(object):

    def __init__(self, value, parent=None, children=[]):

        self.value = value
        self.parent = parent
        self.children = children

    def insertChildren(self, children=[]):
        self.children += children

    def insertChild(self, child):
        self.children.append(child)


if __name__ == '__main__':
    tree = Tree(1)

    #tree.node_list contains a list of nodes, their parent is correct
    #tree.root.children contains all children
    #tree.node_list[x] contains the same children - although many of them should not even have a single child. Otherwise the recursion would not end.

【问题讨论】:

    标签: python-3.x recursion tree member


    【解决方案1】:

    对此要非常非常谨慎:

    def __init__(self, value, parent=None, children=[]):
    

    还有这个:

    def insertChildren(self, children=[]):
    

    初始值——由 [] 创建的列表对象——是共享的单个对象。广泛。

    您正在广泛使用这个单一、共享的默认列表对象。

    您可能想改用它。

    def __init__( self, value, parent= None, children= None ):
        if children is None: children= []
    

    此技术将创建一个新的空列表对象。不分享。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 2018-10-21
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多