2016-12-06 6 views
1

필자는 내 인생에서 내 코드가 KeyError를 던지는 이유를 알 수 없습니다. 값이 거기에 있어야한다고 생각합니다. 나는 처음에 그것들을 모두 더했습니다. for loop 그리고 그것들을 추가 한 목록은 비어 있지 않습니다. 그럼 왜 54 번 라인이 KeyError를 끊임없이 던지나요? 나는 내가 방금 무언가를 간과했다라고 확신한다. 그러나 하루 종일 이것으로 일하고 난 후에, 나는 꽤 붙이게된다.내 코드가 KeyError를 계속 던지는 이유는 무엇입니까?

사용되는 함수 (graph() 및 shortest_path() 등)는 here입니다.

{string value: [list of string values that are groupings of the values in the dictionary's keys]} 

tagUsers는 다음과 같은 구조를 가지고 : 사전에

{string value: [grouped lists of string values found in edgeData]} 

감사

edgeData는 다음과 같은 구조를 가지고 있습니다.

from collections import defaultdict, deque 
import json 

class Graph(object): 
    def __init__(self): 
     self.nodes = set() 
     self.edges = defaultdict(list) 
     self.distances = {} 

    def add_node(self, value): 
     self.nodes.add(value) 

    def add_edge(self, from_node, to_node, distance): 
     self.edges[from_node].append(to_node) 
     self.edges[to_node].append(from_node) 
     self.distances[(from_node, to_node)] = distance 


def dijkstra(graph, initial): 
    visited = {initial: 0} 
    path = {} 

    nodes = set(graph.nodes) 

    while nodes: 
     min_node = None 
     for node in nodes: 
      if node in visited: 
       if min_node is None: 
        min_node = node 
       elif visited[node] < visited[min_node]: 
        min_node = node 
     if min_node is None: 
      break 

     nodes.remove(min_node) 
     current_weight = visited[min_node] 

     for edge in graph.edges[min_node]: 
      try: 
       weight = current_weight + graph.distances[(min_node, edge)] 
      except: 
       continue 
      if edge not in visited or weight < visited[edge]: 
       visited[edge] = weight 
       path[edge] = min_node 

    return visited, path 


def shortest_path(graph, origin, destination): 
    visited, paths = dijkstra(graph, origin) 
    full_path = deque() 
    _destination = paths[destination] 

    while _destination != origin: 
     full_path.appendleft(_destination) 
     _destination = paths[_destination] 

    full_path.appendleft(origin) 
    full_path.append(destination) 

    return visited[destination] 
if __name__ == '__main__': 
    edgeData = {'a': ['c', 'd'], 'b': ['d'], 'c': ['d'], 'd': ['a', 'b']} 
    tagUsers = {'hashtag1': ['a', 'c', 'd'], 'hashtag2': ['b'], 'hashtag3': ['b', 'd']} 
    shortestpaths = {} 

    graph = Graph() 

    users = [] 


    # calls function, builds graph with data in edgeData 
    for key, value in edgeData.items(): 
     users.append(key) 
     graph.add_node(key) 

     for each in value: 
      graph.add_edge(key, each, 1) 

    # determines how many users used each hashtag 
    hashtags = {} 
    for key, value in tagUsers.items(): 
     tmpTags = key 
     count = len(value) 
     hashtags[key] = count 

    # normally determines which hashtag was used the most 
    # Here, it's pre-set 
    topTag = ['hashtag1'] 

    # calculates the shortest path from each user to another user 
    # that uses the most-used hashtag 
    count = 0 
    if count < 1: 
     for key, value in edgeData.items(): 
      tmpDict = {} 
      for tag in topTag: 
       shortest = 10000 
       for k, v in tagUsers.items(): 
        if k == tag: 
         for each in v: 
          flag = False 
          if key != each 
           flag = True 
           tmpShort = shortest_path(graph, key, each) 
           if tmpShort < shortest: 
            shortest = tmpShort 
       if flag: 
        tmpDict[tag] = shortest 
      shortestpaths[key] = tmpDict 
      count += 1 

목표는 mdsrosa의 상단 해시 태그

함수 호출

를 사용하는 다른 사용자에게 최단 거리가이 코드를 참조하고, 예의에 각 사용자에 대해 포함하는 shortestpaths의 데이터입니다 github.

shortest_path  Origin:a Destination:a 
paths: {'c': 'a', 'b': 'd', 'd': 'a'} 
Traceback (most recent call last): 
    File "e.py", line 43, in <module> 
    tmpShort = dj.shortest_path(graph, key, each) 
    File "E:\kiribati\dijkstra.py", line 61, in shortest_path 
    _destination = paths[destination] 
KeyError: 'a' 

:에

def shortest_path(graph, origin, destination): 
    print 'shortest_path  Origin:%s Destination:%s' % (origin, destination) 
    visited, paths = dijkstra(graph, origin) 
    full_path = deque() 
    print 'paths: %s' % paths 
    _destination = paths[destination] 

결과

즉, 에러 _destination '에서 shortest_path() 던져 얻는다 = _destination]

+0

그것을 던지고 실제 데이터를 설명 뭔가, shortest_path

for k, v in tagUsers.items(): if k == tag: for each in v: if key == each: continue tmpShort = dj.shortest_path(graph, key, each) if tmpShort < shortest: shortest = tmpShort tmpDict[tag] = shortest 

는 또한 k에서 루프 변수를 변경 v, key, value, each를 호출하기 전에 체크 if key == each를 추가하는 것입니다 오류? 해시 태그에 관한 것입니까? 'defaultdict'가되기를 원했을 것 같습니다. – JeremyK

+0

'tmpDict'에 대한 조작이 모두 잘못되었습니다. 잘못된 루프가 반복 될 때마다 새로운 빈 dict을'tmpDict'에 할당하고,'shortestpaths'에 삽입 한 직후에 dict을'clear '합니다. – user2357112

+4

'for k, v tagUsers.items() : if k == tag :'- 완전히 dict의 요점을 놓치고 있습니다. – user2357112

답변

1

shortest_path 일부 로깅 추가 경로 문제를 도시 출발지와 목적지가 같은 가장자리 케이스를 처리해야합니다.

하나의 옵션은

+0

당신은 당신의 문자열을 인용 할 필요가 있습니다 :'dj.shortest_path (그래프, 'a', 'd')' 'shortest_path 출발지 : a 목적지 : d 경로 : { 'c': 'a', 'b' (1, [ 'a', d '])' – JeremyK

+0

그래, 일하게. 나는이 대답을 받아 들일 것이고, 위에 제공된 샘플 데이터와 함께 아름답게 작동한다. 다시 한 번 고마워, 나는 너의 도움을 대단히 감사한다. – jguberman