【问题标题】:Python - Different recursive result if append to list or add to the listPython - 如果附加到列表或添加到列表,则不同的递归结果
【发布时间】:2020-10-17 22:37:56
【问题描述】:

蛮力下面的代码创建了一个城市图,然后通过 DFS 运行它以找到最短路径。无论我使用“visited.append(node)”还是“visited=visited + [node]”,我得到的结果都不同。追加到列表不正确找不到最短路径。

DFS 中的打印是为了调试为什么存在差异,但我无法确定差异是什么。谁能给我解释一下这个细节?谢谢!

def CreateGraph(cities):
  g={}
  for city in cities:
    g[city]=[]
  return g

def AddRouteToGraph(g,src,dest):
  if src in g and dest in g:
    g[src].append(dest)
  else:
    raise ValueError

cities=['Bmore', 'DC', 'SanFran', 'Philly', 'Seattle', 'NYC']
g=CreateGraph(cities)
AddRouteToGraph(g,'Bmore','Seattle')
AddRouteToGraph(g,'Bmore','Philly')
AddRouteToGraph(g,'Philly','NYC')
AddRouteToGraph(g,'DC','NYC')
AddRouteToGraph(g,'SanFran','Philly')
AddRouteToGraph(g,'SanFran','DC')
AddRouteToGraph(g,'SanFran','Seattle')
AddRouteToGraph(g,'Seattle','DC')
 
def DFS_shortest(g,node,dest,visited,shortest):
  visited.append(node)
  #visited=visited + [node]
  print(f'visited={visited} of type {type(visited)}')
  if node==dest:
    return visited
  for city in g[node]:
    if city not in visited:
      if shortest!=None:
        print(city, str(len(visited)), str(len(shortest)))
      else:
        print(city, str(len(visited)), 'None')
      if shortest==None or len(visited)<len(shortest):
        newPath=DFS_shortest(g,city,dest,visited,shortest)
        if newPath!=None:
          shortest=newPath
  return shortest

print(DFS_shortest(g,'Bmore','NYC',[],None))

【问题讨论】:

    标签: python list recursion


    【解决方案1】:

    通过visited = visited + ...,您正在创建列表的一个新实例,该实例独立于上一层递归。

    当您使用visited.append(...) 时,您正在修改同一个对象实例,因此,当您将其传递给递归时,较低级别的更改实际上会修改您在较高级别的列表

    【讨论】:

      【解决方案2】:

      这是因为当您将 visited 列表传递给其他方法时,会传递一个引用,因此在这些方法中所做的任何更改(例如追加)都会影响原始 visited 列表。

      但是,当您使用 visited = visited + [node] 时,会创建一个新列表并将其传递给其他方法。

      例如考虑

      def func(l):
          # l.append(1)
      
          l = l + [1]
          if len(l) < 10:
              func(l)
      
      l = []
      func(l)
      print(l)
      
      

      试试看,你看就懂了。

      • 使用l.append(1)

      输出,

      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
      

      原来的列表l已经改变了。

      • 使用l = l + [1]

      输出,

      []
      

      原来的列表l没有改变。

      【讨论】:

      • Alain 和 CaptainDaVinci - 感谢您快速而完整的回复。很有帮助!
      猜你喜欢
      • 1970-01-01
      • 2017-03-28
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      相关资源
      最近更新 更多