Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-自定义树的异常行为_Python_List_Tree - Fatal编程技术网

Python-自定义树的异常行为

Python-自定义树的异常行为,python,list,tree,Python,List,Tree,我需要通过在Python脚本中使用树以非常特定的方式对列表进行排序,因此我编写了自己的QuickTreeNode类。然而,在将子节点附加到节点时,我发现了非常奇怪的行为,我真的无法理解发生了什么 下面是课堂: class TreeNode: children = [] identity = "" def __init__(self, node_id, c = []): self.identity = node_id self.child

我需要通过在Python脚本中使用树以非常特定的方式对列表进行排序,因此我编写了自己的QuickTreeNode类。然而,在将子节点附加到节点时,我发现了非常奇怪的行为,我真的无法理解发生了什么

下面是课堂:

class TreeNode:

    children = []
    identity = ""

    def __init__(self, node_id, c = []):
        self.identity = node_id
        self.children = c

    def get_id(self):
        return self.identity

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

    def remove_child(self, child):
        self.children.remove(child)

    def get_children(self):
        return self.children

    def walk(self):
        yield self
        for child in self.children:
            for n in child.walk():
                yield n

    def find_id(self, node_id):
        if self.identity == node_id:
            return self
        for child in self.children:
            found = child.find_id(node_id)
            if found:
                return child
        return None
发生的事情是,当我将一个子元素附加到树中时,该子元素的子元素列表被实例化为长度为1,并且第一个元素是对同一个子元素的引用。因此,子元素中的第一个元素也有一个长度为1的子元素列表,也指向同一个节点,并且它看起来无限长

这里是一个可视化的“树”后,只有一个单一的元素已附加到根节点

我不知道这里发生了什么,我希望其他更熟悉Python的人能够启发我。整个下午都在烦我

def __init__(self, node_id, c = []):
问题是您的
c=[]
。函数的默认参数在Python中只计算一次。因此,当您第一次初始化树节点并更改
c
时,
c
将在下次创建新树节点时保留更改的值,因为它是一个列表,他们不会每次创建新列表,他们只会继续引用完全相同的列表。您将使用与父节点相同的
子节点
列表初始化子节点

这是您想要的:

def __init__(self, node_id, c = None):
    if c is None:
        c = []

这是因为每次初始化TreeNode时都会创建一个新的空列表。在以前的设置中,您每次都在修改完全相同的列表,因为Kevin在其评论中链接到了一个问题。

\uuu init\uuuu
中的
c=[]
看起来确实可疑。你熟悉“陷阱”吗?我不熟悉。我现在就用谷歌搜索。你能分享你如何创造孩子的代码吗?谢谢,这就解决了问题。对我来说是个全新的问题。总是有新的东西要学!我会尽快接受,所以会让我。虽然也许应该归功于凯文。@Luke Python充满了这样复杂的事情;我最近才知道这个问题,可能是几天前,所以你不是唯一一个在那里的人。