2011-12-18 26 views
14

De otra función, tengo tuplas como esta ('falseName', 'realName', positionOfMistake), por ej. ('Milter', 'Miller', 4). Tengo que escribir una función que crea un diccionario de esta manera:python diccionario de diccionarios

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

La función tiene que tener un diccionario y una tupla como la de arriba, como argumentos.

que estaba pensando algo como esto para un comienzo:

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

Pero no está funcionando y estoy tipo de stucked aquí.

+0

que eres muesca está mal. y qué es exactamente lo que no funciona? – yurib

+2

El 'tup' en el parámetro está siendo arrastrado por la línea 'tup = previ ..'. El código parece que no tienes una idea general en tu cabeza. Supongo que se detendrá, se alejará de la computadora, tomará una respiración profunda, saldrá a caminar, se sentará, cerrará los ojos y escribirá el código con lápiz y papel. – matiu

Respuesta

15

Si es sólo para agregar una nueva tupla y está seguro de que no se produzcan colisiones en el diccionario interior se puede hacer esto:

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

La prueba has_key está mejor escrita 'if tup [0] not in d:' –

+0

okay - is that for perfomance? – aweis

+1

http://stackoverflow.com/questions/1323410/has-key-or-in –

10

Usando collections.defaultdict es un gran ahorro de tiempo cuando estás construyendo dicts y no sabes de antemano qué teclas vas a tener.

Aquí se usa dos veces: para el dict resultante y para cada uno de los valores en el 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 

Combinando esto con su código:

dictionary = aggregate_names(previousFunction(string)) 

o para probar: setdefault

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

del diccionario es una buena manera de actualizar una entrada dict existente si está allí, o crear una uno nuevo si no es todo de una vez:

Estilo de bucle:

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

ahora es igual a:

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