2011-12-18 200 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}}