为什么我会出现这个关键错误?(Python)

为什么我会出现这个关键错误?(Python),python,python-3.x,Python,Python 3.x,我试着运行我的Dijkstra函数两次,这样我就能计算出3个点之间的最短距离。当我运行一次时,它工作正常,但两次在第38行和第44行返回一个键错误 代码: graph={'c1':{'c2':4,'L1':3},'c2':{'c1':4,'c3':3,'L1':2.5},'c3':{'c2':3,'c2':2} def dijkstra(图表、开始、目标): 最短距离={} 前置={} 未选节点=图 无穷大=浮点('inf') 路径=[] 对于未选定节点中的节点: 最短距离[节点]=无穷大 最短

我试着运行我的Dijkstra函数两次,这样我就能计算出3个点之间的最短距离。当我运行一次时,它工作正常,但两次在第38行和第44行返回一个键错误

代码:

graph={'c1':{'c2':4,'L1':3},'c2':{'c1':4,'c3':3,'L1':2.5},'c3':{'c2':3,'c2':2}
def dijkstra(图表、开始、目标):
最短距离={}
前置={}
未选节点=图
无穷大=浮点('inf')
路径=[]
对于未选定节点中的节点:
最短距离[节点]=无穷大
最短距离[起点]=0
#打印(最短距离)
在未选定时:
minNode=None
对于未选定节点中的节点:
如果minNode为None:
minNode=节点
elif最短_距离[节点]<最短_距离[节点]:
minNode=节点
对于childNode,图[minNode]中的权重。项()
如果权重+最短距离[minNode]<最短距离[childNode]:
最短_距离[childNode]=权重+最短_距离[minNode]
前置[childNode]=minNode
未命名。pop(minNode)
当前节点=目标
而currentNode!=开始:
尝试:
插入路径(0,currentNode)
currentNode=前置[currentNode]
除KeyError外:
打印('路径不可访问')
打破
路径.插入(0,开始)
如果最短距离[目标]!=无穷:
打印('最短距离:'+str(最短距离[目标])
打印('路径:'+str(路径))
dijkstra(图“L1”、“c2”)
dijkstra(图“c2”、“c3”)
以下是我得到的错误:

Path not reachable
    dijkstra(graph, 'c2', 'c3')
  File "E:\Work\Delivery_API\Delivery.py", line 38, in dijkstra
    if shortest_distance[goal] != infinity:
KeyError: 'c3'

执行
unseenodes=graph
时,将变量
unseenodes
绑定到
graph
引用的相同的dict

这意味着在
未指定节点上所做的任何更改也将反映在
图形上

因此,在第一个
dijkstra(图'L1','c2')
中,一切进展顺利

但是,在运行期间,您执行了一些
unseenodes.pop(minNode)
,这同样等同于执行
graph.pop(minNode)
。所以当你做dijkstra(图'c2','c3')
的时候,你的图已经改变了,看起来不像你想象的那样。这就是为什么它只运行一次就可以工作的原因


最简单的补救办法是复制一份
图形
,以确保它完好无损。您只需将赋值更改为:
unseenodes=dict(graph)
。这将创建
图形
副本
未搜索节点
现在引用另一个单独的dict,而不是
图形
引用的dict)。

执行
未搜索节点=图形
时,将变量
未搜索节点
绑定到
图形
引用的相同的dict

这意味着在
未指定节点上所做的任何更改也将反映在
图形上

因此,在第一个
dijkstra(图'L1','c2')
中,一切进展顺利

但是,在运行期间,您执行了一些
unseenodes.pop(minNode)
,这同样等同于执行
graph.pop(minNode)
。所以当你做dijkstra(图'c2','c3')
的时候,你的图已经改变了,看起来不像你想象的那样。这就是为什么它只运行一次就可以工作的原因


最简单的补救办法是复制一份
图形
,以确保它完好无损。您只需将赋值更改为:
unseenodes=dict(graph)
。这将创建
图形
副本
未指定的
现在引用另一个单独的dict,而不是
图形所引用的dict)。

非常感谢。我只是将数据结构从图形复制粘贴到看不见的节点。我应该用更优雅的方式来做还是这样好?再次感谢!在我看来,这(我的解决方案)是完全正确的。你不能绕开它,最终你需要
图形来处理它。你只是不想改变原来的。因此,您可以创建一个副本,从中删除节点,而不必担心。我只是将数据结构从图形复制粘贴到看不见的节点。我应该用更优雅的方式来做还是这样好?再次感谢!在我看来,这(我的解决方案)是完全正确的。你不能绕开它,最终你需要
图形来处理它。你只是不想改变原来的。因此,您可以创建一个副本,从中删除节点