python中path + = [newpath]和path = path + [newpath]有什么区别

时间:2019-03-12 13:54:38

标签: python

在下面的函数中,当我使用path = path + [start]时,我将得到结果['A', 'B', 'E'],但是当我使用path += [start]时,我将得到结果['A', 'B', 'D', 'E']。为什么?

我的代码:

graph1 = {'A':['B','C'],
          'B':['A','D','E'],
          'C':['A','F'],
          'D':['B'],
          'E':['B','F'],
          'F':['C','E']}

def find_path(graph,start,end,path=[]):

    path = path + [start]

    if start == end:
        return path
    if start not in graph:
        return None

    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph,node,end,path)
            if newpath:
                return newpath 
    return None

print(find_path(graph1,'A','E'))

3 个答案:

答案 0 :(得分:3)

这里发生了两件事:

首先,您对path=[]的定义中的find_pathmutable default argument,如果您不期望这样做,它的行为将非常令人惊讶。简短的版本是path的默认值并非每次都是新的[],而是每次相同 []

第二,path = path + [start] 将名称path重新绑定到由串联创建的新list对象,而path += [start] 将< / em> list指向的现有path对象。为了进一步了解这种区别,我可以想到的最佳资源是文章Facts and myths about Python names and values

两者的组合意味着您每次都在更改相同列表;如果您更改它们中的任何一个,您将获得单独的列表对象,并且不会看到此问题。

答案 1 :(得分:0)

问题来自find_path定义中使用可变值作为默认参数。

  • 当您使用path += [start]时,实际上是在更改默认值 的path
  • 使用path = path + [start]时,您实际上存储了 更改之前,请在局部path中使用path个参数。

更多细节here

答案 2 :(得分:0)

不幸的是,对于列表,Python重载+=的含义与list.extend相同(在所有情况下,而不仅仅是当差异不可见时),因此它将用RHS 就地,而普通二进制文件+将创建一个全新的列表对象,在其中复制LHS,然后在其中复制RHS。

这在这里很明显,因为在Python中,默认值是在模块解析期间创建的,并且绑定到函数本身,因此每次调用该函数时都不会得到新值。因此,如果您就地修改path(这是+=所做的),它将保留在函数调用之间。