【问题标题】:What is difference between res.append(val) and res[:]+[value]?res.append(val) 和 res[:]+[value] 有什么区别?
【发布时间】:2020-11-17 04:25:14
【问题描述】:
def dfs(node, target: int, path: List[int]):
        if isLeaf(node):
            if target - node.val == 0:
                result.append(path[:] + [node.val])
            return
        if target < 0:
            return
        
        if node.left:
            dfs(node.left, target - node.val, path[:] + [node.val])
        if node.right:
            dfs(node.right, target - node.val, path[:] + [node.val])

在上述方法中,如果我使用 "path[:] + [node.val]" 我将在结果中得到一个列表列表 ([[1,2,3,4],[1,2, 3,5]])。但是如果我使用“path.append(node.val)”而不是“path[:] + [node.val]”,我会得到列表的空列表([[],[]])。那么如果我们使用递归,我们应该传递新构造的列表的新副本吗?

【问题讨论】:

  • 旁注:res[:]+[value] 完全等同于res + [value],除了它毫无意义地复制(可能很大)res+ 已经在执行浅拷贝了,所以使用 [:] 显式地进行浅拷贝只是浪费。

标签: python-3.x list recursion


【解决方案1】:

path[:] + [x][*path, x] 相同,后者会复制 path 列表,并在末尾插入 x

result.append(x) 将改变(修改)现有的result 并在列表末尾插入x

那么如果我们使用递归,我们应该传递新构造的列表的新副本吗?

是的。递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳结果。这意味着要避免变量重新分配、单分支 (if) 条件和其他副作用。

这是修改后的dfs 的外观 -

def dfs(node, target: int, path: List[int]):
  if not node or target < 0:
    return
  elif isLeaf(node) and target - node.val == 0:
    yield [*path, node.val]
  else:
    yield from dfs(node.left, target - node.val, [*path, node.val])
    yield from dfs(node.right, target - node.val, [*path, node.val])

接近尾声,您可以看到一些计算值重复 -

def dfs(node, target: int, path: List[int]):
  if not node or target < 0:
    return
  elif isLeaf(node) and target - node.val == 0:
    yield [*path, node.val]
  else:
    new_target = target - node.val  # <- compute once
    new_path = [*path, node.val]    # <- compute once
    yield from dfs(node.left, new_target, new_path)
    yield from dfs(node.right, new_target, new_path)

现在您可以使用 for..in 逐步遍历您的树 -

for path in dfs(my_tree):
  print(path)

# [...]
# [...]
# [...]

或者在list 中收集所有路径-

print(list(dfs(my_tree))
# [ [...], [...], [...] ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 2016-11-22
    • 2016-02-27
    相关资源
    最近更新 更多