2011-12-18 204 views
14

从另一个函数,我有这样的元组,例如('falseName', 'realName', positionOfMistake)('Milter', 'Miller', 4)。 我需要编写一个函数,使一个字典是这样的:python词典的字典

D={realName:{falseName:[positionOfMistake], falseName:[positionOfMistake]...}, 
    realName:{falseName:[positionOfMistake]...}...} 

功能必须采取字典和前面一样的元组,作为参数。

我想这样的一个开始:

def addToNameDictionary(d, tup): 
    dictionary={} 
    tup=previousFunction(string) 
    for element in tup: 
     if not dictionary.has_key(element[1]): 
      dictionary.append(element[1]) 
    elif: 
     if ... 

但它不工作,我也有点stucked这里。

+0

你缩进是错误的。什么不起作用? – yurib 2011-12-18 09:51:05

+2

参数中的'tup'正在被'tup = previ ..'行消失。该代码看起来像你没有把头脑中的大图片。我估计停下来,离开电脑,深吸一口气,散步,坐下,闭上眼睛,用铅笔和纸写下代码。 – matiu 2011-12-18 10:08:16

回答

15

如果只是增加一个新的记录,你一定是没有冲突在内部字典,你可以这样做:当你

def addNameToDictionary(d, tup): 
    if tup[0] not in d: 
     d[tup[0]] = {} 
    d[tup[0]][tup[1]] = [tup[2]] 
+3

has_key测试写得更好'如果tup [0]不在d:' – 2011-12-18 09:55:15

+0

没关系 - 是否为perfomance? – aweis 2011-12-18 09:57:23

+1

http://stackoverflow.com/questions/1323410/has-key-or-in – 2011-12-18 09:58:30

10

使用collections.defaultdict是一个很大的节省时间建立字典,事先不知道你将拥有哪些键。

这里使用了两次:对于结果字典和字典中的每个值。

import collections 

def aggregate_names(errors): 
    result = collections.defaultdict(lambda: collections.defaultdict(list)) 
    for real_name, false_name, location in errors: 
     result[real_name][false_name].append(location) 
    return result 

与您的代码组合是:

dictionary = aggregate_names(previousFunction(string)) 

或者测试:

EXAMPLES = [ 
    ('Fred', 'Frad', 123), 
    ('Jim', 'Jam', 100), 
    ('Fred', 'Frod', 200), 
    ('Fred', 'Frad', 300)] 
print aggregate_names(EXAMPLES) 
8

字典的setdefault是,如果它的存在,以更新现有的字典条目,或创建一个好办法新的一个,如果它不是全部在一个去:

循环风格:

# This is our sample data 
data = [("Milter", "Miller", 4), ("Milter", "Miler", 4), ("Milter", "Malter", 2)] 

# dictionary we want for the result 
dictionary = {} 

# loop that makes it work 
for realName, falseName, position in data: 
    dictionary.setdefault(realName, {})[falseName] = position 

词典现在等于:

{'Milter': {'Malter': 2, 'Miler': 4, 'Miller': 4}}