it-swarm-pt.tech

Dicionário de dicionários em Python?

De outra função, tenho tuplas como esta ('falseName', 'realName', positionOfMistake), por exemplo. ('Milter', 'Miller', 4). Eu preciso escrever uma função que faça um dicionário como este:

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

A função precisa usar um dicionário e uma tupla como acima, como argumentos.

Eu estava pensando algo assim para começar:

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

Mas não está funcionando e estou meio que preso aqui.

17
Linus Svendsson

Se for apenas para adicionar uma nova tupla e você tiver certeza de que não há colisões no dicionário interno, faça isso:

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

Usando collections.defaultdict economiza muito tempo quando você está construindo ditados e não sabe de antemão quais chaves terá.

Aqui é usado duas vezes: para o ditado resultante e para cada um dos valores no ditado.

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

Combinando isso com o seu código:

dictionary = aggregate_names(previousFunction(string))

Ou para testar:

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

o setdefault do dicionário é uma boa maneira de atualizar uma entrada de dict existente, se ela estiver lá, ou criar uma nova se não estiver tudo de uma só vez:

Estilo de loop:

# 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

dicionário agora é igual a:

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