【问题标题】:Python: Use sets in conjunction with dictionariesPython:将集合与字典结合使用
【发布时间】:2013-05-25 09:45:20
【问题描述】:

我这里有这个方法,它以字典的形式生成有向图,其中键的值是键指向的节点,即 {'stack': ['over','flow'] },堆栈指向over and flow...

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

我的问题是,我怎样才能实现集合与字典的使用,以防止与所讨论的键相同的值被添加到键中?

【问题讨论】:

  • 为什么要进行深度复制?
  • 为什么不在这里测试if j not in heroList
  • deepcopying 是这样我可以删除一个键,而不是从我使用的主字典中删除键
  • @MartijnPieters 我正在考虑使用它,但我的图表很大,有 100000 多个键,因此在效率方面没有帮助。我想知道是否可以使用集合实现相同的效果,同时不会对效率产生太大影响。
  • 如果没有更多关于heroDict 内容的详细信息,我对此不能多说,但看起来简单的graph[j].extend(e for e in i if e != j) 就可以了;这也会创建一个新列表。

标签: python dictionary set


【解决方案1】:

以下是我将如何重新编码您的图形生成器;使用 csv modulecollections.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

这里不需要使用集合。请注意,我使用了更有意义的变量名;尽量避免使用ij,除非它们是整数索引。

【讨论】:

  • 我在使用此方法时遇到关键错误。任何想法为什么?
  • 关键错误是什么?请注意,我忘记设置 graph = defaultdict(list) 直到 1 分钟前。
  • 发生在 graph[name].extend(n for n in names if n != name) 行,它只是说 KeyError: 然后是第一个键的名称
  • 这意味着graph 不是defaultdict。添加graph = defaultdict(list) 行,您就设置好了。
  • 是的,它就像一个魅力,也非常有效。非常感谢您的帮助,我非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
相关资源
最近更新 更多