Словарь словарей словаря python

Из другой функции у меня есть кортежи вроде ('falseName', 'realName', positionOfMistake), например. ('Milter', 'Miller', 4). Мне нужно написать функцию, которая делает словарь следующим образом:

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 ...

Но он не работает, и я как бы застрял здесь.

Ответы

Ответ 1

Если нужно добавить новый кортеж, и вы уверены, что во внутреннем словаре нет коллизий, вы можете сделать это:

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

Ответ 2

Использование collections.defaultdict - большая экономия времени, когда вы строите dicts и не знаете заранее, какие ключи у вас будут.

Здесь он используется дважды: для полученного dict и для каждого из значений в dict.

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)

Ответ 3

dictionary setdefault - хороший способ обновить существующую запись dict, если она есть, или создать новую, если она не все за один раз:

Тип петли:

# 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}}