web-dev-qa-db-fra.com

Python Erreur clé = 0 - Impossible de trouver l'erreur Dict dans le code

en gros, je me suis creusé la cervelle pendant un bon moment maintenant pour savoir pourquoi mon code ne fonctionne pas, j'ai testé des pièces séparément et j'ai cherché sur le Web pour voir si cela pouvait aider, en vain. Je reçois une erreur indiquant que le retraçage est:

Traceback (most recent call last):
File "yes2.py", line 62, in <module>
g.add_Edge(row_index,col_index, b)
File "yes2.py", line 27, in add_Edge
self.adj[u].append(Edge) 
KeyError: 0

Les deux parties avec des erreurs sont

    def add_Edge(self, u, v, w=0): 
    if u == v: 
        raise ValueError("u == v") 
    Edge = Edge(u,v,w) 
    redge = Edge(v,u,0) 
    Edge.redge = redge 
    redge.redge = Edge 
    self.adj[u].append(Edge) #### LINE 27 ####
    self.adj[v].append(redge) 
    self.flow[Edge] = 0 
    self.flow[redge] = 0 

et

g = FlowNetwork()
map(g.add_vertex, ['0','1','2','3','4','5','6'])
with open('network.txt', "r") as file:
for row_index, row in enumerate(file):
    for col_index, value in enumerate(row.split(",")):
        b = int(value)
        if b != 0:
            g.add_Edge(row_index,col_index, b) ### LINE 62 ####

Et voici le code terminé, car sans cela, il peut être difficile de voir ce qui se passe

class Edge(object):
def __init__(self, u, v, w):
    self.source = u
    self.sink = v 
    self.capacity = w 
def __repr__(self): 
    return "%s->%s:%s" % (self.source, self.sink, self.capacity) 

class FlowNetwork(object): 
def __init__(self): 
    self.adj = {} 
    self.flow = {} 

def add_vertex(self, vertex): 
    self.adj[vertex] = [] 

def get_edges(self, v): 
    return self.adj[v] 

def add_Edge(self, u, v, w=0): 
    if u == v: 
        raise ValueError("u == v") 
    Edge = Edge(u,v,w) 
    redge = Edge(v,u,0) 
    Edge.redge = redge 
    redge.redge = Edge 
    self.adj[u].append(Edge) 
    self.adj[v].append(redge) 
    self.flow[Edge] = 0 
    self.flow[redge] = 0 

def find_path(self, source, sink, path): 
    if source == sink: 
        return path 
    for Edge in self.get_edges(source): 
        residual = Edge.capacity - self.flow[Edge] 
        if residual > 0 and not (Edge,residual) in path: 
            result = self.find_path( Edge.sink, sink, path + [(Edge,residual)] ) 
            if result != None: 
                return result 

def max_flow(self, source, sink): 
    path = self.find_path(source, sink, []) 
    while path != None: 
        flow = min(res for Edge,res in path) 
        for Edge,res in path: 
            self.flow[Edge] += flow 
            self.flow[Edge.redge] -= flow 
        path = self.find_path(source, sink, []) 
    return sum(self.flow[Edge] for Edge in self.get_edges(source)) 

g = FlowNetwork()
map(g.add_vertex, ['0','1','2','3','4','5','6'])
with open('network.txt', "r") as file:
# enumerate allows you to iterate through the list with an index and an object
for row_index, row in enumerate(file):
    # split allows you to break a string apart with a string key
    for col_index, value in enumerate(row.split(",")):
        #convert value from string to int
        b = int(value)
        if b != 0:
            g.add_Edge(row_index,col_index, b)

print g.max_flow('1','6')

Merci beaucoup pour votre temps, très apprécié.

11
user3573321

L'erreur que vous obtenez est que self.adj N'a pas déjà de clé 0. Vous essayez d'ajouter à une liste qui n'existe pas encore.

Pensez à utiliser un defaultdict à la place, en remplaçant cette ligne (dans __init__):

self.adj = {}

avec ça:

self.adj = defaultdict(list)

Vous devrez importer en haut:

from collections import defaultdict

Maintenant, plutôt que d'augmenter un KeyError, self.adj[0].append(Edge) créera automatiquement une liste à ajouter.

10
mhlester

La solution defaultdict est meilleure. Mais pour être complet, vous pouvez également vérifier et créer une liste vide avant l'ajout. Ajoutez les lignes +:

+ if not u in self.adj.keys():
+     self.adj[u] = []
  self.adj[u].append(Edge)
.
.
3
gaoithe

Essaye ça:

class Flonetwork(Object):
    def __init__(self,adj = {},flow={}):
        self.adj = adj
        self.flow = flow
0
oof