【问题标题】:Python: printing all nodes of tree unintentionally stores dataPython:打印树的所有节点无意中存储数据
【发布时间】:2013-07-29 17:59:37
【问题描述】:

我通过创建 Node 对象在 python 中创建了一个通用树。每个节点可以有 0、1 或 2 棵树。

我正在尝试创建一种方法来打印树中所有节点的列表。该列表不必按顺序排列。这是我的简单尝试:

def allChildren(self, l = list()):
    l.append(self)
    for child in self.children:
        l = child.allChildren(l)
    return l

我第一次运行此方法时,它可以正常工作。但是,由于某种原因,它正在存储以前的运行。我第二次运行该方法时,它会将所有节点打印两次。即使我创建了 2 个单独的树,它仍然会记住以前的运行。例如:我创建了 2 棵树,a 和 b。如果我运行 a.allChildren() 我会收到正确的结果。然后我运行 b.allChildren() 并接收 a 的所有节点和 b 的所有节点。

【问题讨论】:

    标签: python class python-3.x tree


    【解决方案1】:

    您有一个可变值作为函数参数l 的默认值。在 Python 中,这意味着当您调用 l.append(self) 时,您正在永久修改默认参数。

    为了避免这个问题,每次调用函数时都设置l为一个新的列表,如果没有传入列表:

    def allChildren(self, l = None):
        if l is None:
            l = list()
        l.append(self)
        for child in self.children:
            l = child.allChildren(l)
        return l
    

    this question 对这种现象进行了更彻底的解释。

    【讨论】:

      【解决方案2】:

      试试这个:

      def allChildren(self, l = None):
          if(l==None):
              l = list()
      
          l.append(self)
          for child in self.children:
              l = child.allChildren(l)
          return l
      

      并查看this answer 以获得解释。

      【讨论】:

        【解决方案3】:

        如果你正在编写像 l = list() 这样的默认参数,它会在编译函数时创建列表,因此它会为所有函数调用创建一个列表实例。为防止这种情况,请使用 None 并在函数内创建新列表:

        def allChildren(self, l = None):
            if not l: l = []
            l.append(self)
            for child in self.children:
                l = child.allChildren(l)
            return l
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-30
          相关资源
          最近更新 更多