Python字典键错误'0',但字典中为0

时间:2019-05-13 09:59:11

标签: python python-3.x dictionary graph dijkstra

在图类中,我制作了一个vertList字典,用于存储顶点名称和顶点类对象,该字典在调用Dijkstra函数时会在Relax函数中抛出键错误0。

我尝试使用get函数,而不是直接从字典本身进行调用。

from collections import defaultdict
import math
import heapq


class PriorityQueue:
    def __init__(self):
        self.is_empty = True
        self.length = 0
        self.pqueue = []

    def makePQueue(self, l):
        self.pqueue = l.copy()
        heapq.heapify(self.pqueue)
        if(len(l) > 0):
            self.length = len(l)
            self.is_empty = False

    def addElement(self, element):
        heapq.heappush(self.pqueue, element)
        self.length = self.length+1

    def removeElement(self):
        if(self.length > 0):
            element = heapq.heappop(self.pqueue)
            self.length = self.length-1
            if(self.length == 0):
                self.is_empty = True
            return element
        else:
            return None


# vertex class

class Vertex:
    def __init__(self, key):
        self.id = key
        self.parent = None
        self.distFromSource = math.inf

    def getId(self):
        return self.id

    def getParent(self):
        return self.parent

    def addParent(self, p):
        self.parent = p

    def getDistSource(self):
        return self.distFromSource

    def setDistFromSource(self, d):
        self.distFromSource = d

# Graph class


class Graph:
    def __init__(self):
        self.graph = defaultdict(list)
        self.soruce = None
        self.vertList = {}

    def addVertex(self, v):

        if(v not in list(self.vertList.keys())):
            ver = Vertex(v)
            self.vertList[v] = ver

    def addEdge(self, u, v, c):
        if(u not in list(self.vertList.keys())):
            ver = Vertex(u)
            self.vertList[u] = ver
        if(v not in list(self.vertList.keys())):
            ver = Vertex(v)
            self.vertList[v] = ver
        self.graph[u].append((v, c))

    def getWeight(self, u, v):
        # binary search can be implemented for speed
        for i in self.graph[u]:
            if(i[0] == v):
                return i[1]

    def setSource(self, s):
        if(s not in list(self.vertList.keys())):
            ver = Vertex(s)
            self.vertList[s] = ver
        self.vertList[s].setDistFromSource(0)
        self.source = self.vertList[s]
        self.source.setDistFromSource(0)

    def getSource(self):
        return self.source.getId()

    def getDistList(self):
        l = [(self.vertList[i].getDistSource(), str(i))
             for i in list(self.vertList.keys())]
        return l

    # def costArray(self):
        # l = [i.]
    # implementation of edge array of cost

    def relax(self, u, v, c):
        if(self.vertList[v].getDistSource() > self.vertList[u].getDistSource()+c):
            self.vertList[v].setDistFromSource(
                self.vertList[u].getDistSource()+c)
            self.vertList[v].addParent(self.vertList[u])


def dijkstra(graph):
    ss = []
    l = graph.getDistList()
    pq = PriorityQueue()
    pq.makePQueue(l)
    # print(pq.pqueue)
    while(pq.is_empty == False):
        (cost, u) = pq.removeElement()
        # in priority queue on the basis of cost
        if int(u) not in ss:
            ss = ss.append(int(u))
            for (i, c) in graph.graph[int(u)]:
                graph.relax(u, i, c)
```

g = Graph()

g.addEdge(0, 1, 3)

g.addEdge(0, 2, 2)

g.addEdge(0, 3, 5)

g.addEdge(1, 0, 3)

g.addEdge(1, 4, 3)

g.addEdge(4, 1, 3)

g.addEdge(4, 2, 1)

g.addEdge(4, 6, 4)

g.addEdge(2, 0, 2)

g.addEdge(2, 4, 1)

g.addEdge(2, 5, 6)

g.addEdge(3, 0, 5)

g.addEdge(3, 5, 2)

g.addEdge(5, 2, 6)

g.addEdge(5, 3, 2)

g.addEdge(5, 6, 1)

g.addEdge(5, 7, 4)

g.addEdge(6, 4, 4)

g.addEdge(6, 5, 1)

g.addEdge(6, 7, 2)

g.addEdge(7, 5, 4)

g.addEdge(7, 6, 2)

g.setSource(0)

dijkstra(g)

例外

python graph.py

Traceback (most recent call last):

  File "graph.py", line 155, in <module>

    dijkstra(g)

  File "graph.py", line 126, in dijkstra

    graph.relax(u, i, c)

  File "graph.py", line 108, in relax

    if(self.vertList[v].getDistSource() > 

self.vertList[u].getDistSource()+c):

KeyError: '0'

2 个答案:

答案 0 :(得分:2)

调用relax()方法时,u是一个字符串,而不是整数!

这就是为什么出现KeyError的原因:确实有一个0键,但是没有'0'

定义优先级队列时,将显式存储字符串:

def getDistList(self):
    l = [(self.vertList[i].getDistSource(), str(i))
         for i in list(self.vertList.keys())]
    return l

然后,在您的dijkstra方法中,将该字符串转换为if语句中的int,但之后不进行graph.relax()调用中的转换:

if int(u) not in ss:
    ss = ss.append(int(u))
    for (i, c) in graph.graph[int(u)]:
        graph.relax(u, i, c)

答案 1 :(得分:0)

在进行进一步调试之前,我将检查Graph类的属性 soruce ,我认为它是 source ,并且您输入了错误的代码,作为函数定义在类图形 getSource 返回 self.source.getId()