为什么会收到此Key错误? (蟒蛇)

时间:2020-05-28 08:42:23

标签: 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, 'L1':2}, 'L1':{'c1':3, 'c2':2.5, 'c3':2}}

def dijkstra(graph, start, goal):
    shortest_distance = {}
    predecessor = {}
    unseenNodes = graph
    infinity = float('inf')
    path = []

    for node in unseenNodes:
        shortest_distance[node] = infinity
    shortest_distance[start] = 0
    #print(shortest_distance)

    while unseenNodes:
        minNode = None
        for node in unseenNodes:
            if minNode is None:
                minNode = node
            elif shortest_distance[node] < shortest_distance[minNode]:
                minNode = node
        for childNode, weight in graph[minNode].items():
            if weight + shortest_distance[minNode] < shortest_distance[childNode]:
                shortest_distance[childNode] = weight + shortest_distance[minNode]
                predecessor[childNode] = minNode
        unseenNodes.pop(minNode)

    currentNode = goal
    while currentNode != start:
        try:
            path.insert(0, currentNode)
            currentNode = predecessor[currentNode]
        except KeyError:
            print('Path not reachable')
            break
    path.insert(0, start)

    if shortest_distance[goal] != infinity:
        print('Shortest distance: ' + str(shortest_distance[goal]))
        print('Path:' + str(path))

dijkstra(graph, 'L1', 'c2')
dijkstra(graph, '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'

1 个答案:

答案 0 :(得分:3)

执行unseenNodes = graph时,将变量unseenNodes绑定到由graph引用的相同字典。

这意味着在unseenNodes上所做的任何更改也会在<{> {1}} 上反映。

因此,在第一个graph中一切顺利。

,在此运行期间,您执行了一些dijkstra(graph, 'L1', 'c2'),这再次相当于执行unseenNodes.pop(minNode)。因此,到您进行graph.pop(minNode)时,您的图表已经改变,看起来并不像您想的那样。这就是为什么仅运行一次即可使用的原因。

简单的补救方法是处理dijkstra(graph, 'c2', 'c3')的副本,以确保其完好无损。您需要做的就是将分配更改为:graph。这样会创建unseenNodes = dict(graph)副本({{1}现在引用了另一个单独的字典,而不是graph引用的字典)。