Словарь словарей в Python? - PullRequest
17 голосов
/ 18 декабря 2011

Из другой функции у меня есть такие кортежи, как ('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 ...

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

Ответы [ 3 ]

16 голосов
/ 18 декабря 2011

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

def addNameToDictionary(d, tup):
    if tup[0] not in d:
        d[tup[0]] = {}
    d[tup[0]][tup[1]] = [tup[2]]
10 голосов
/ 18 декабря 2011

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

Здесь это используется дважды: для результирующего диктата,и для каждого из значений в 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)
8 голосов
/ 18 декабря 2011

словарь 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}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...