2014-06-06 6 views
5

Ho un dizionario che creo come questo:Errore chiave del dizionario Python durante l'assegnazione: come faccio a evitare questo?

myDict = {} 

Poi mi piace aggiungere chiave in esso che corrisponde a un altro dizionario, in cui ho messo un altro valore:

myDict[2000]['hello'] = 50 

Così, quando ho passare myDict[2000]['hello'] da qualche parte, darebbe 50.

Perché Python non sta creando le voci proprio lì? Qual è il problema? Pensavo che KeyError si verifica solo quando provi a leggere una voce che non esiste, ma la sto creando proprio qui?

risposta

11

KeyError si verifica perché si sta tentando di leggere una chiave inesistente quando si tenta di accedere a myDict[2000]. In alternativa, è possibile utilizzare defaultdict:

>>> from collections import defaultdict 
>>> myDict = defaultdict(dict) 
>>> myDict[2000]['hello'] = 50 
>>> myDict[2000] 
{'hello': 50} 

defaultdict(dict) significa che se myDict incontra una chiave sconosciuta, verrà restituito un valore predefinito, in questo caso, tutto ciò che è restituito da dict(), che è un dizionario vuoto.

5

Ma si sono cercando di leggere una voce che non esiste: myDict[2000].

La traduzione esatta di ciò che dici nel tuo codice è "dammi la voce in myDict con la chiave del 2000, e memorizza 50 contro la chiave 'ciao' in quella voce." Ma myDict non ha una chiave del 2000, quindi l'errore.

Ciò che è effettivamente necessario è creare quella chiave. Potete farlo in una volta sola:

myDict[2000] = {'hello': 50} 
+4

Ciò cancellerà qualsiasi voce esistente per altre chiavi in ​​'myDict [2000]', comunque. Probabilmente vale la pena considerare un 'defaultdict (dict)'. – user2357112

0

Hai ragione, ma nel tuo pitone codice deve prima ottenere myDict [2000] e poi fare l'assegnazione. Poiché tale voce non esiste, non può assegnare ai suoi elementi

3

quello che vuoi è a implement a nested dict:

vi consiglio questo approccio:

class Vividict(dict): 
    def __missing__(self, key): 
     value = self[key] = type(self)() 
     return value 

Dalla documentazione, sotto d[key]

New in version 2.5: If a subclass of dict defines a method __missing__(), if the key key is not present, the d[key] operation calls that method with the key key as argument

Per provarlo:

myDict = Vividict() 

myDict[2000]['hello'] = 50 

e myDict ora ritorna:

{2000: {'hello': 50}} 

E questo funziona per qualsiasi profondità arbitraria che si desidera:

myDict['foo']['bar']['baz']['quux'] 

funziona.