python 中的列表附加差异

Discrepancy of list append in python

当我使用 append(path)append(list(path))

时,我得到了不同的结果

我有以下代码来查找总和的所有路径:

class TreeNode:
  def __init__(self, val, left=None, right=None):
    self.val = val
    self.left = left
    self.right = right


def find_paths(root, sum):
  allPaths = []
  
  dfs(root, sum, [], allPaths)

  return allPaths

def dfs(root, sum, path, res):
  if not root:
    return
  
  path.append(root.val)
  if root.val == sum and root.left is None and root.left is None:
    res.append(path)
  
  dfs(root.left, sum - root.val, path, res)
  dfs(root.right, sum - root.val, path, res)

  del path[-1]
  

def main():

  root = TreeNode(12)
  root.left = TreeNode(7)
  root.right = TreeNode(1)
  root.left.left = TreeNode(4)
  root.right.left = TreeNode(10)
  root.right.right = TreeNode(5)
  sum = 23
  print("Tree paths with sum " + str(sum) +
        ": " + str(find_paths(root, sum)))


main()

这有以下输出:

Tree paths with sum 23: [[], []]

但是,如果我将 res.append(path) 更改为 res.append(list(path)),那么 return 将得到正确答案 Tree paths with sum 23: [[12, 7, 4], [12, 1, 10]]。我很困惑为什么使用 list 操作会改变答案。

res.append(path) 将对象 path 本身附加到列表 res。在该行之后,当您修改 path 对象(如 del path[-1])时,修改也会应用于 res 中的附加对象,因为,嗯,它们是同一个对象。

list(path),另一方面,“复制”path。所以这个现在是与 path 不同的对象。之后修改 path 时,修改不会传播到这个不同的对象。

如果您使用 path[:]path.copy() 而不是 list(path),您将得到相同的结果。

res.append(path) 附加实际的 path 对象,而不是它的副本。因此,如果 path 稍后更改,更改也会出现在 res 中。

res.append(list(path)) 附加一个副本。