当前位置: 首页 > 知识库问答 >
问题:

递归编辑成员变量:所有实例都有相同的值

米夕
2023-03-14

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

每个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.

共有1个答案

唐兴思
2023-03-14

对此要非常谨慎:

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

这是:

def insertChildren(self, children=[]):

初始值(由[]创建的列表对象)是共享的单个对象。普遍地

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

你可以用这个来代替。

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

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

 类似资料:
  • 如果我在代码中选择了一个变量(而不仅仅是任何字符串),那么该变量的所有其他实例都会在它们周围画一个笔划(白色轮廓): 是否有一个快捷键可以让我选择变量的所有实例并一次编辑它们? D、K、U让我逐一选择它们,但我必须手动排除非变量字符串匹配: 使用CtrlG只需选择所有匹配的字符串: 显然,Sublime能够区分变量匹配和字符串匹配。难道没有办法只选择变量匹配吗?

  • 问题内容: 也许这比技术问题更像是一种样式问题,但是我有一个包含多个成员变量的类,并且我想让它起作用,以便在用户第一次创建该类的实例时初始化一些成员变量(即在该功能),我想其他的成员变量从成员函数参数,将稍后被称为定义。所以我的问题是我应该初始化函数中的所有成员变量(并将稍后定义的变量设置为虚拟值)还是初始化函数中的某些成员以及后续函数中的某些成员变量。我意识到这可能很难理解,因此这里有一些示例。

  • 问题内容: 是否可以使用相同的值替换格式化字符串中的所有变量? 就像是: 会回来的 问题答案: 有可能,但是必须修改格式字符串,必须使用 显式参数索引 : 显式参数索引: 在Printf,Sprintf和Fprintf中,默认行为是为每个格式化动词格式化在调用中传递的连续参数。但是,动词前的符号[n]表示第n个单索引参数将被格式化。宽度或精度的’*’之前的相同符号选择保存该值的参数索引。在处理了带

  • 为什么单子里的牌都一样?我尝试了,但输出仍然相同。 Main.java 产出: Lorem ipsum dolor sit amet,consectetur adipiscing Elit。Aenean nisl.curabitur ac arcu ornare,aliquet eros eu,pretium massa.

  • 问题内容: 我将如何完成? 我敢肯定有一个非常明显的答案。现在只是在逃避我。 问题答案: 是的,他们可以使用相同的名称。但是,要引用实例变量,您需要使用前缀:

  • 问题内容: 在Java中,实例变量和方法可以具有相同的名称而没有任何不稳定或冲突吗? 我想确保是否可以摆脱它的编译问题,以免造成任何错误。 问题答案: 是的,这很好,主要是因为在语法上,它们的用法不同。