I'm trying to run this code but I get AttributeError:
File "D:/QGIS TRAINING/Masir/dkj.py", line 98, in
print(graph.dijkstra("905577", "703920")) AttributeError: 'list' object has no attribute 'dijkstra'
I make list from a csv file and set it as an input to my algorithm
here is my code
import csv
from collections import deque, namedtuple
with open('D:/QGIS TRAINING/Masir/yal zero.csv', 'r') as f:
reader = csv.reader(f)
list_nodes = list(reader)
# we'll use infinity as a default distance to nodes.
inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')
def make_edge(start, end, cost=1):
return Edge(start, end, cost)
class Graph:
def __init__(self, edges):
# let's check that the data is right
wrong_edges = [i for i in edges if len(i) not in [2, 3]]
if wrong_edges:
raise ValueError('Wrong edges data: {}'.format(wrong_edges))
self.edges = [make_edge(*edge) for edge in edges]
#property
def vertices(self):
return set(
sum(
([edge.start, edge.end] for edge in self.edges), []
)
)
def get_node_pairs(self, n1, n2, both_ends=True):
if both_ends:
node_pairs = [[n1, n2], [n2, n1]]
else:
node_pairs = [[n1, n2]]
return node_pairs
def remove_edge(self, n1, n2, both_ends=True):
node_pairs = self.get_node_pairs(n1, n2, both_ends)
edges = self.edges[:]
for edge in edges:
if [edge.start, edge.end] in node_pairs:
self.edges.remove(edge)
def add_edge(self, n1, n2, cost=1, both_ends=True):
node_pairs = self.get_node_pairs(n1, n2, both_ends)
for edge in self.edges:
if [edge.start, edge.end] in node_pairs:
return ValueError('Edge {} {} already exists'.format(n1, n2))
self.edges.append(Edge(start=n1, end=n2, cost=cost))
if both_ends:
self.edges.append(Edge(start=n2, end=n1, cost=cost))
#property
def neighbours(self):
neighbours = {vertex: set() for vertex in self.vertices}
for edge in self.edges:
neighbours[edge.start].add((edge.end, edge.cost))
return neighbours
def dijkstra(self, source, dest):
assert source in self.vertices, 'Such source node doesn\'t exist'
distances = {vertex: inf for vertex in self.vertices}
previous_vertices = {
vertex: None for vertex in self.vertices
}
distances[source] = 0
vertices = self.vertices.copy()
while vertices:
current_vertex = min(
vertices, key=lambda vertex: distances[vertex])
vertices.remove(current_vertex)
if distances[current_vertex] == inf:
break
for neighbour, cost in self.neighbours[current_vertex]:
alternative_route = distances[current_vertex] + cost
if alternative_route < distances[neighbour]:
distances[neighbour] = alternative_route
previous_vertices[neighbour] = current_vertex
path, current_vertex = deque(), dest
while previous_vertices[current_vertex] is not None:
path.appendleft(current_vertex)
current_vertex = previous_vertices[current_vertex]
if path:
path.appendleft(current_vertex)
return path
graph = list_nodes
print(graph.dijkstra("905577", "703920"))
is it something wrong with my list or with the algorithm?
There's the problem with the way you instantiate the graph object. You see, this:
graph = list_nodes
is a list of nodes from list_nodes = list(reader).
But this:
graph = Graph(list_nodes)
is probably what you actually want.
Just in case, here's a DigitalOcean tutorial on object construction
Related
Here is my code for Dijkstra's Algorithm.
I have declared a "Vertex" class and a "Graph" class.
I am using heapq module and heapifying the list "unvisitedQueue" of tuples. But even then an error shows up saying " TypeError: '<' not supported between instances of 'Vertex' and 'Vertex' " even when "v.getDistance()" returns either 0 or float('inf').
import heapq
class Vertex:
def __init__(self, node):
self.id = node
self.adjacent = {}
self.previous = None
self.distance = float('inf')
def addNeighbor(self, neighbor, weight = 0):
self.adjacent[neighbor] = weight
def getConnections(self):
return self.adjacent.keys()
def getVertex_ID(self):
return self.id
def getWeight(self, neighbor):
return self.adjacent[neighbor]
def setDistance(self, dist):
self.distance = dist
def getDistance(self):
return self.distance
def setPrevious(self, prev):
self.previous = prev
def __str__(self):
return str(self.id) + "adjacent : " + str([x.id for x in self.adjacent])
class Graph:
def __init__(self):
self.vertDictionary = {}
self.numVertices = 0
def __iter__(self):
return iter(self.vertDictionary.values())
def addVertex(self, node):
self.numVertices += 1
newVertex = Vertex(node)
self.vertDictionary[node] = newVertex
return newVertex
def getVertex(self, node):
if node in self.vertDictionary:
return self.vertDictionary[node]
else:
return None
def addEdge(self, frm, to, cost = 0):
if frm not in self.vertDictionary:
self.addVertex(frm)
if to not in self.vertDictionary:
self.addVertex(to)
self.vertDictionary[frm].addNeighbor(self.vertDictionary[to], cost)
self.vertDictionary[to].addNeighbor(self.vertDictionary[frm], cost)
def getVertices(self):
return self.vertDictionary.keys()
def setPrevious(self, current):
self.previous = current
def getPrevious(self):
return self.previous
def getEdges(self):
edges = []
for v in G:
for w in v.getConnections():
v_id = v.getVertex_ID()
w_id = w.getVertex_ID()
edges.append((v_id, w_id, v.getWeight(w)))
return edges
def Dijkstra(G, s):
source = G.getVertex(s)
source.setDistance(0)
visited = {}
unvisitedQueue = [(v.getDistance(), v) for v in G]
heapq.heapify(unvisitedQueue)
while len(unvisitedQueue):
uv = heapq.heappop(unvisitedQueue)
currVert = uv[1]
visited[currVert] = True
for nbr in currVert.getConnections():
if currVert.getDistance() + currVert.getWeight(nbr) < nbr.getDistance():
nbr.setDistance(currVert.getDistance() + currVert.getWeight(nbr))
print("Updated: Current = %s Neighbour = %s New Distance = %s" %(currVert.getVertex_ID(), nbr.getVertex_ID(), nbr.getDistance()))
else:
print("Not Updated: Current = %s Neighbour = %s Distance = %s" %(currVert.getVertex_ID(), nbr.getVertex_ID(), nbr.getDistance()))
while len(unvisitedQueue):
heapq.heappop(unvisitedQueue)
unvisitedQueue = [(v.getDistance(), v) for v in G if v not in visited]
heapq.heapify(unvisitedQueue)
for v in G:
print(source.getVertex_ID(), "to", v.getVertex_ID(), "-->", v.getDistance())
ERROR -->
Traceback (most recent call last):
File "d:\Python\Final 450\Graph\Dijkstra's_Algo.py", line 124, in <module>
print(Dijkstra(G, "a"))
File "d:\Python\Final 450\Graph\Dijkstra's_Algo.py", line 86, in Dijkstra
heapq.heapify(unvisitedQueue)
TypeError: '<' not supported between instances of 'Vertex' and 'Vertex'
The error is happening because tuples are compared lexicographically. If two distances are the same, the comparison moves on to the Vertex objects themselves.
Two solutions readily come to mind. The first is simply to add a unique index to the tuple before the Vertex but after the distance. This is easy, and would work even if you didn't have access to the Vertex class:
unvisitedQueue = [(v.getDistance(), i, v) for i, v in enumerate(G) if v not in visited]
The second option is to modify Vertex to have a __lt__ magic method:
def __lt__(self, other):
return self.getDistance() < other.getDistance()
This is nice because you can heapify more directly now:
unvisitedQueue = [v for v in G if v not in visited]
I have to calculate the centrality degree on a graph. My implementation is:
import csv
class Graph:
'''
Representation of a simple graph using an adjacency map.
There exist nested Classes for Vertex and Edge objects and
useful methods for vertex and edge, edge incidence and
vertex degree retrieval plus edge and vertex insertion
'''
# == Class Vertex == #
class Vertex:
'''
Class for representing vertex structure for a graph.
'''
__slots__ = '_element'
def __init__(self, x):
'''
Do not call constructor directly. Use Graph's insert_vertex(x).
'''
self._element = x
def element(self):
'''
Return element associated with this vertex.
'''
return self._element
def __hash__(self):
'''
will allow vertex to be a map/set key
'''
return hash(self._element)
def __repr__(self):
return '{0}'.format(self._element)
def __eq__(self, other):
if isinstance(other, Graph.Vertex):
return self._element == other._element
return False
# == Class Edge == #
class Edge:
'''
Class for representing edge structure for a graph.
'''
__slots__ = '_origin', '_destination', '_weight'
def __init__(self, u, v, x):
'''
Do not call constructor directly. Use Graph's insert_edge(x).
'''
self._origin = u
self._destination = v
self._weight = x
def endPoints(self):
'''
Return (u,v) tuple for vertices u and v.
'''
return (self._origin, self._destination)
def opposite(self, v):
'''
Return the vertex that is opposite v on this edge.
'''
return self._destination if self._origin == v else self._origin
def element(self):
'''
Return element associated with this edge.
'''
return self._weight
def __hash__(self):
'''
will allow edge to be a map/set key
'''
return hash((self._origin, self._destination))
def __repr__(self):
if self._weight is None:
return '({0}, {1})'.format(self._origin, self._destination)
return '({0}, {1}, {2})'.format(self._origin, self._destination, self._weight)
# == Class Graph == #
def __init__(self, directed=False):
'''
Create an empty graph (undirected, by default).
Graph is directed if optional parameter is set to True.
'''
self._outgoing = {}
self._incoming = {} if directed else self._outgoing
def __getitem__(self, arg):
return self._incoming[arg]
def is_directed(self):
'''
Return True if graph is directed
'''
return self._outgoing is not self._incoming
def vertex_count(self):
'''
Return the vertices count
'''
return len(self._outgoing)
def vertices(self):
'''
Return an iterator over the graph's vertices
'''
return self._outgoing.keys()
def get_vertex(self, el):
'''
Return the graph's vertex with corresponding element
equal to el. Return None on failure
'''
for vertex in self.vertices():
if vertex.element() == el:
return vertex
return None
def edges_count(self):
'''
Return the edges count
'''
edges = set()
for secondary_map in self._outgoing.values():
edges.update(secondary_map.values())
return len(edges)
def edges(self):
'''
Return a set of graph's edges
'''
edges = set()
for secondary_map in self._outgoing.values():
edges.update(secondary_map.values())
return edges
def get_edge(self, u, v):
'''
Return the edge from u to v
'''
return self._outgoing[u].get(v)
def degree(self, v, outgoing=True):
'''
Return the number of incident vertices to v
If graph is directed then handle the case of indegree
'''
inc = self._outgoing if outgoing else self._incoming
return len(inc[v])
def incident_edges(self, v, outgoing=True):
'''
Return all incident edges to node v.
If graph is directed, handle the case of incoming edges
'''
inc = self._outgoing if outgoing else self._incoming
if v not in inc:
return None
for edge in inc[v].values():
yield edge
def adjacent_vertices(self, v, outgoing=True):
'''
Return adjacent vertices to a given vertex
'''
if outgoing:
if v in self._outgoing:
return self._outgoing[v].keys()
else:
return None
else:
if v in self._incoming:
return self._incoming[v].keys()
else:
return None
def insert_vertex(self, x=None):
'''
Insert and return a new Vertex with element x
'''
for vertex in self.vertices():
if vertex.element() == x:
# raise exception if vertice exists in graph
# exception can be handled from the class user
return vertex
v = self.Vertex(x) # cria um objeto do tipo Vertex
self._outgoing[v] = {}
if self.is_directed:
self._incoming[v] = {}
return v
def insert_edge(self, u, v, x=None):
'''
Insert and return a new Edge from u to v with auxiliary element x.
'''
if (v not in self._outgoing) or (v not in self._outgoing):
# raise exception if one of vertices does not exist
# exception can be handled from the class user
raise Exception('One of the vertices does not exist')
if self.get_edge(u, v):
# no multiple edges
# exception can be handled from the class user
e = self.Edge(u, v, x)
return e
e = self.Edge(u, v, x) # cria um objeto do tipo Edge
self._outgoing[u][v] = e
self._incoming[v][u] = e
return e
def remove_edge(self, u, v):
if not self.get_edge(u, v):
# exception for trying to delete non-existent edge
# can be handled from class user
raise Exception('Edge is already non-existent.')
u_neighbours = self._outgoing[u]
del u_neighbours[v]
v_neighbours = self._incoming[v]
del v_neighbours[u]
def remove_vertex(self, x):
'''
Delete vertex and all its adjacent edges from graph
'''
if (x not in self._outgoing) and (x not in self._incoming):
raise Exception('Vertex already non-existent')
secondary_map = self._outgoing[x]
for vertex in secondary_map:
# delete reference to incident edges
if self.is_directed():
del self._incoming[vertex][x]
else:
del self._outgoing[vertex][x]
# delete reference to the vertex itself
del self._outgoing[x]
def printG(self):
'''Mostra o grafo por linhas'''
print('Grafo Orientado:', self.is_directed())
'''Mostra o número de vertices'''
print("Número de Vertices: {}".format(G.vertex_count()))
'''Mostra o número de arestas'''
print("Número de Arestas: {}".format(G.edges_count()))
for v in self.vertices():
print('\nUser: ', v, ' grau_in: ', self.degree(v, False), end=' ')
if self.is_directed():
print('grau_out: ', self.degree(v, False))
for i in self.incident_edges(v):
print(' ', i, end=' ')
if self.is_directed():
for i in self.incident_edges(v, False):
print(' ', i, end=' ')
My graph is constructed from a CSV file:
def read_csv(filename):
G = Graph() # cria um objeto do tipo Graph
with open(filename, 'r') as csv_file: # abre o ficheiro csv
data = csv.reader(csv_file)
next(data) # ignora a primeira coluna do ficheiro
for linha in data: # por cada linha no ficheiro
id_origem = linha[0] # a origem é a primeira coluna do ficheiro
id_destino = linha[1] # o destino é a segunda coluna do ficheiro
peso = linha[2] if len(linha) > 2 else 1 # se não existir uma terceira coluna do ficheiro
# assume-se que o peso das arestas, é 1
v_origem = G.insert_vertex(id_origem) # insere o vertex no grafo
v_destino = G.insert_vertex(id_destino) # insere o vertex no grafo
G.insert_edge(v_origem, v_destino, int(peso)) # insere a aresta no grafo
return G
CSV file has the structure:
follower,followed,distance
Murphy,Thornton,45
Perkins,Walters,26
Perkins,Bradley,7
Lawrence,Hart,15
The shortest distance are calculated by:
def shortest_path_lengths(g, src):
d = {}
cloud = {}
pq = AdaptableHeapPriorityQueue()
pqlocator = {}
source = Graph.Vertex(src)
for v in G.vertices():
if v == source:
d[v] = 0
else:
d[v] = float('inf')
pqlocator[v] = pq.add(d[v], v)
while not pq.is_empty():
key, u = pq.remove_min()
cloud[u] = key
del pqlocator[u]
for e in G.incident_edges(u):
v = e.opposite(u)
if v not in cloud:
wgt = e.element()
if d[u] + wgt < d[v]:
d[v] = d[u] + wgt
pq.update(pqlocator[v], d[v], v)
return cloud
I'm calculating the centrality degree from:
def centrality_degree(G, src=None):
distances = []
closeness_centr = []
short = shortest_path_lengths(G, src)
#print(short)
vertex_number = G.vertex_count()
#while contador <= len(short):
#for vertex in G.vertices(): #G.adjacent_vertices(G.get_vertex(src)):
for value in short.values():
if value != float('inf'):
distances.append(value)
print(distances)
soma = sum(distances)
#print(soma)
formula = (vertex_number-1)/soma
closeness_centr.append(formula)
print(closeness_centr)
Is there any way to caculate the centrality degree without passing the parameter src?
Try:
def centrality_degree(G):
n_vertex = ...
# compute all the shortest paths from the node i to j
# (do a for in a for)
degree = ...
return degree
Hi everyone I cannot figure out how to fix this issue and from my knowledge it's because of the attributes of the object's I am using.
For your information, I am making a graph in Python and the graph needs to check if all the vertices and edges are connected.
class graph(object):
def __init__(self, gdict=None):
if gdict == None:
gdict = {}
self.gdict = gdict
# return the keys of the dictionary list, or vertices
def getVertice(self):
return list(self.gdict.keys())
# this allows us to obtain the edges for the graph
# or "values" of the dict key
def getEdges(self):
return self.generate_edges()
def addVertex(self, vertex):
if vertex not in self.gdict:
self.gdict[vertex] = []
def addEdge(self, edge):
edge = set(edge)
(vertex1, vertex2) = tuple(edge)
if vertex1 in self.gdict:
self.gdict[vertex1].append(vertex2)
else:
self.gdict[vertex1] = [vertex2]
# this generates a list of all edges for the vertices
def generate_edges(self):
edges = []
for vertex in self.gdict:
for neighbour in self.gdict[vertex]:
if (neighbour, vertex) not in edges:
edges.append((vertex, neighbour))
return edges
def find_path(self, startVertex, endVertex, paths=None):
if paths == None:
paths = []
graphs = self.gdict
paths = paths + [startVertex]
if startVertex == endVertex:
return paths
if startVertex not in graphs:
return None
for vertex in graphs[startVertex]:
if vertex not in paths:
extendedPath = self.find_path(vertex, endVertex, paths)
if extendedPath:
return extendedPath
return None
def findAllPath(self, startVertex, endVertex, paths=None):
if paths is None:
paths = []
graphs = self.gdict
paths = paths + [startVertex]
if startVertex == endVertex:
return [paths]
if startVertex not in graphs:
return []
paths = []
for vertex in graphs[startVertex]:
if vertex not in paths:
extendedPath = self.find_path(vertex, endVertex, paths)
for p in extendedPath:
paths.append(p)
return paths
def findisovertices(self): ##reword this
""" returns a list of isolated vertices. """
graphs = self.gdict
iso = []
for vertex in graphs:
print(iso, vertex)
if not graphs[vertex]:
iso += [vertex]
return iso
def isConnected(self, verticesMet=None, startVertex=None):
if verticesMet is None:
verticesMet = set()
gdict = self.gdict
vertices = self.gdict()
if not startVertex:
startVertex = vertices[0]
verticesMet.add(startVertex)
if len(verticesMet) != len(vertices):
for vertex in gdict[startVertex]:
if vertex not in verticesMet:
if self.isConnected(verticesMet, vertex):
return True
else:
return True
return False
# this function prints the nodes/vertices in the graph
def completeGraph(self):
Vertex = len(self.gdict.keys())
Edges = len(self.gdict.values())
answer = 2.0 * Edges / (Vertex * (Vertex - 1))
return answer
graph_elements = ({"a": ["d", "f"],
"b": ["c"],
"c": ["b", "c", "d", "e"],
"d": ["a", "c"],
"e": ["c"],
"f": ["a"],
"z": []
})
g = graph(graph_elements)
print("Our vertices are: \n", g.getVertice())
print("#1 | Generate list of all edges: \n", graph.generate_edges(g))
##2 Function to calculate isolated nodes of graph.
isolated = graph.findisovertices(g)
print("#2 | Find isolated nodes:\n", isolated)
# 3. Function to find a path from a start vertex to an end vertex
path = graph.find_path(g, "a", "c")
print("#3 | Find a path function: \n", path)
# 4. Function to find all the paths between a start vertex to an end vertex
allPaths = graph.findAllPath(g, "a", "e")
print("#4 | All paths function:\n", allPaths)
# 5. Function to check if graph is connected
connect = graph(g)
print("#5 | Connected graph function \n", connect.isConnected(g))
and I keep receiving the following error:
Traceback (most recent call last):
File "graphsAssign6.py", line 160, in <module>
print("#5 | Connected graph function \n", connect.isConnected(g))
File "graphsAssign6.py", line 95, in isConnected
vertices = self.gdict()
TypeError: 'graph' object is not callable
def isConnected(self, verticesMet=None, startVertex=None):
if verticesMet is None:
verticesMet = set()
gdict = self.gdict
vertices = self.getVertice()
if not startVertex:
startVertex = vertices[0]
verticesMet.add(startVertex)
if len(verticesMet) != len(vertices):
for vertex in gdict[startVertex]:
if vertex not in verticesMet:
if self.isConnected(verticesMet, vertex):
return True
else:
return True
return False
# 5. Function to check if graph is connected
print("#5 | Connected graph function \n", g.isConnected())
Don't make a new connect = graph(g). Your isConnected should work within g. Also, you shouldn't get your vertices with self.gdict(). It doesn't make sense and you already have a function named getVertice for that job.
I'm reading ThinkComplexity book, I'm new to python, so I have this code:
class Graph(dict):
def __init__(self, vs=[], es=[]):
"""
:param vs: list of vertices/nodes in the graph
:param es: list of edges/connection for the nodes
:return: Object graph
"""
for v in vs:
self.add_vertex(v) #also node
for e in es:
self.add_edge(e) #arc/edge/line
def add_vertex(self, v):
"""
:param v: Add the node/vertex to the graph
:return: Nothing just add
"""
self[v] = {}
def add_edge(self, e):
"""
:param e: Add arc/edge/line to the graph here is in both directions as it is undirected graph, if there is a arc already replace it
:return: Nothing just add
"""
v, w = e
self[v][w] = e
self[w][v] = e
def get_edge(self, v1, v2):
try:
if self != None:
if self[v1][v2] == self[v2][v1]:
print 'got it'
return True
except:
return None
def remove_edge(self, e, e2):
try:
if self != None:
del self[e][e2]
del self[e2][e]
print 'deleted\n', e[0], e[1]
return True
except:
return None
def vertices(self): #get the list of nodes
nodes = []
for node in self.keys():
nodes.append(node.label)
print nodes, '\n'
return nodes
def edges(self):
list_edges = []
count = 0
for node in self:
for edges in self[node]:
count += 1
print self[node].values(), count
list_edges.append(self[node].values())
return list_edges
def out_vertices(self, v): #nodes connected to this node
connected = []
for node in v.keys():
connected.append(node)
print node, 'this node is connected to', v.keys()
return connected
def out_edges(self, v):
list_out_edges = []
for ed in v.values():
print ed, 'edges from to'
list_out_edges.append(ed)
return list_out_edges
class Vertex(object): #nodes fro the graph
def __init__(self, label=''):
self.label = label
def __repr__(self):
return 'Vertex/Node(%s)' % repr(self.label)
__str__= __repr__
class Edge(tuple):
def __new__(cls, e1, e2):
return tuple.__new__(cls, (e1, e2))
def __repr__(self):
return 'Edge(%s---%s) <-undirected' % (repr(self[0]), repr(self[1]))
__str__ = __repr__
In chapter 2 4. Write a method named remove_edge that takes an edge and removes all references to it from the graph.
I have the get_edge() code done, but t remove I don't know how to do it, any help?? This would be an starting point to do a Bayes Network, so I want to learn about python and graphs. Thanks
Like this:
def remove_edge(g, e, e2):
try:
if g != None:
del g[e][e2]
del g[e2][e]
print 'deleted\n', e[0], e[1]
return True
except:
return None
The keys in the dictionary can be objects, no only str. And need to do it both ways because is undirected
I've run into a problem with my code, i'm not able to calculate the distance to a node from the starting node. I have a text file of the form:
1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,9
This represents the node distances in the graph. Here is my code, unfortunately, despite trying a few different methods I still keep coming up with various error messages.
infinity = 1000000
invalid_node = -1
startNode = 0
class Node:
distFromSource = infinity
previous = invalid_node
visited = False
def populateNodeTable():
nodeTable = []
index =0
f = open('route.txt', 'r')
for line in f:
node = map(int, line.split(','))
nodeTable.append(Node())
print nodeTable[index].previous
print nodeTable[index].distFromSource
index +=1
nodeTable[startNode].distFromSource = 0
return nodeTable
def tentativeDistance(currentNode, nodeTable):
nearestNeighbour = []
for currentNode in nodeTable:
# if Node[currentNode].distFromSource + currentDistance = startNode + currentNode
# currentDistance = currentNode.distFromSource + nodeTable.currentNode
currentNode.previous = currentNode
currentNode.length = currentDistance
currentNode.visited = True
currentNode +=1
nearestNeighbour.append(currentNode)
print nearestNeighbour
return nearestNeighbour
def shortestPath (nearestNeighbour)
shortestPath = []
f = open ('spf.txt', 'r')
f.close()
currentNode = startNode
if __name__ == "__main__":
populateNodeTable()
tentativeDistance(currentNode,populateNodeTable())
The lines starting with '#' in my tentativeDistance function is the section giving me trouble. I've looked at some other implementations on the web though they confuse me
I have been programming the Dijkstra's Algorithm in Python a few months ago; its tested and it should work:
def dijkstra(u,graph):
n = graph.numNodes
l = { u : 0 } ; W = graph.V()
F = [] ; k = {}
for i in range(0,n):
lv,v = min([ (l[lk],lk) for lk in l.keys() if lk in W ])
W.remove(v)
if v!=u: F.append(k[v])
for v1 in [ v2 for v2 in graph.G(v) if v2 in W ]:
if v1 not in l or l[v]+graph.w(v,v1) < l[v1]:
l[v1] = l[v] + graph.w(v,v1)
k[v1] = (v,v1)
return l,F
You need a class Graph with Method V() (which yields the graphs nodes), w(v1,v2) (which yields the weight of the edge (v1,v2)), remove (which removes an edge from a graph) and attribute numNodes (which yields the number of nodes in the graph) and G(v) which yields the neighborhood of node v.