2013-05-25 2 views
1

У меня есть этот метод, который генерирует ориентированный граф в виде словаря, где значения ключа являются узлами, на которые указывает ключ, т. Е. {'Stack': [ «над», «поток»]}, стек точек снова и течь ...Python: использование наборов в сочетании со словарями

def generateGraph(fileName): 
    heroDict = {} 
    graph = {} 
    with open(fileName) as inFile: 
     for line in inFile:#go through each line 
      name_comic = line.rstrip().replace('"', '').split('\t') #split into list with name and comic book as strings 
      if name_comic[1] in heroDict: #if the comic book is already in the dictionary 
       heroDict[name_comic[1]] += [name_comic[0]] #add the hero into the comic's list of heroes 
      else: 
       heroDict.update({name_comic[1]: [name_comic[0]]}) # update dictionary with name and comic book 
    for i in heroDict.values(): 
     for j in i: 
      if graph.has_key(j): 
       tempDict = copy.deepcopy(i) 
       tempDict.remove(j) 
       heroList = tempDict 
       graph[j] += heroList 
      else: 
       tempDict = copy.deepcopy(i) 
       tempDict.remove(j) 
       heroList = tempDict 
       graph[j] = heroList 
     print graph #<========== the graph has duplicates, ie, values that are the same as their keys are present 
    return graph 

Мой вопрос, как я могу реализовать использование наборов с словарей, чтобы предотвратить значения, которые являются такими же, как ключ в вопросе, который нужно добавить к ключу?

+0

Зачем нужна глубокая копия? –

+1

И почему бы не просто проверить для 'if j not in heroList' здесь? –

+0

deepcopying - это то, что я могу удалить ключ, не удаляя ключ из основного словаря im, используя – Ogen

ответ

4

Вот как я перекодировал ваш построитель графиков; используя csv module и collections.defaultdict class сделать код значительно более читаемым:

import csv 
from collections import defaultdict 

def generateGraph(fileName): 
    heroDict = defaultdict(list) 

    with open(fileName, 'rb') as inFile: 
     reader = csv.reader(inFile, delimiter='\t') 
     for row in reader: 
      name, comic = row[:2] 
      heroDict[comic].append(name) 

    graph = defaultdict(list) 
    for names in heroDict.itervalues(): 
     for name in names: 
      graph[name].extend(n for n in names if n != name) 
    print graph 
    return graph 

Там нет необходимости использовать наборы здесь. Обратите внимание, что я использовал более значимые имена переменных; старайтесь избегать i и j, если они не являются целыми индексами.

+0

Я получаю ключевые ошибки, когда использую этот метод. Любые идеи почему? – Ogen

+0

Каковы основные ошибки? Обратите внимание, что я забыл установить 'graph = defaultdict (list)' до 1 минуты назад. –

+0

Это происходит на линии ** graph [name] .extend (n для n в именах, если n! = Name) **, и это просто говорит ** KeyError: ** то имя первого ключа – Ogen