Python dictionary key error when assigning – how do I get around this?
Question:
I have a dictionary that I create like this:
myDict = {}
Then I like to add key in it that corresponds to another dictionary, in which I put another value:
myDict[2000]['hello'] = 50
So when I pass myDict[2000]['hello']
somewhere, it would give 50
.
Why isn’t Python just creating those entries right there? What’s the issue? I thought KeyError only occurs when you try to read an entry that doesn’t exist, but I’m creating it right here?
Answers:
But you are trying to read an entry that doesn’t exist: myDict[2000]
.
The exact translation of what you say in your code is “give me the entry in myDict with the key of 2000, and store 50 against the key ‘hello’ in that entry.” But myDict doesn’t have a key of 2000, hence the error.
What you actually need to do is to create that key. You can do that in one go:
myDict[2000] = {'hello': 50}
You’re right, but in your code python has to first get myDict[2000] and then do the assignment. Since that entry doesn’t exist it can’t assign to its elements
KeyError
occurs because you are trying to read a non-existant key when you try to access myDict[2000]
. As an alternative, you could use defaultdict:
>>> from collections import defaultdict
>>> myDict = defaultdict(dict)
>>> myDict[2000]['hello'] = 50
>>> myDict[2000]
{'hello': 50}
defaultdict(dict)
means that if myDict encounters an unknown key, it will return a default value, in this case whatever is returned by dict() which is an empty dictionary.
What you want is to implement a nested dict:
I recommend this approach:
class Vividict(dict):
def __missing__(self, key):
value = self[key] = type(self)()
return value
From the docs, under d[key]
To try it:
myDict = Vividict()
myDict[2000]['hello'] = 50
and myDict now returns:
{2000: {'hello': 50}}
And this will work for any arbitrary depth you want:
myDict['foo']['bar']['baz']['quux']
just works.
According to the below scenario, when you append type new_result
into dict
, you will get KeyError: 'result'
dict = {}
new_result = {'key1':'new_value1','key2':'new_value'}
dict['result'].append(new_result)
Because key doesn’t exist in other words your dict
doesn’t have a result key. I fixed this problem with defaultdict
and their setdefault
method.
To try it;
from collections import defaultdict
dict = defaultdict(dict)
new_result = {'key1':'new_value1','key2':'new_value2'}
dict.setdefault('result', []).append(new_result)
I have a dictionary that I create like this:
myDict = {}
Then I like to add key in it that corresponds to another dictionary, in which I put another value:
myDict[2000]['hello'] = 50
So when I pass myDict[2000]['hello']
somewhere, it would give 50
.
Why isn’t Python just creating those entries right there? What’s the issue? I thought KeyError only occurs when you try to read an entry that doesn’t exist, but I’m creating it right here?
But you are trying to read an entry that doesn’t exist: myDict[2000]
.
The exact translation of what you say in your code is “give me the entry in myDict with the key of 2000, and store 50 against the key ‘hello’ in that entry.” But myDict doesn’t have a key of 2000, hence the error.
What you actually need to do is to create that key. You can do that in one go:
myDict[2000] = {'hello': 50}
You’re right, but in your code python has to first get myDict[2000] and then do the assignment. Since that entry doesn’t exist it can’t assign to its elements
KeyError
occurs because you are trying to read a non-existant key when you try to access myDict[2000]
. As an alternative, you could use defaultdict:
>>> from collections import defaultdict
>>> myDict = defaultdict(dict)
>>> myDict[2000]['hello'] = 50
>>> myDict[2000]
{'hello': 50}
defaultdict(dict)
means that if myDict encounters an unknown key, it will return a default value, in this case whatever is returned by dict() which is an empty dictionary.
What you want is to implement a nested dict:
I recommend this approach:
class Vividict(dict):
def __missing__(self, key):
value = self[key] = type(self)()
return value
From the docs, under d[key]
To try it:
myDict = Vividict()
myDict[2000]['hello'] = 50
and myDict now returns:
{2000: {'hello': 50}}
And this will work for any arbitrary depth you want:
myDict['foo']['bar']['baz']['quux']
just works.
According to the below scenario, when you append type new_result
into dict
, you will get KeyError: 'result'
dict = {}
new_result = {'key1':'new_value1','key2':'new_value'}
dict['result'].append(new_result)
Because key doesn’t exist in other words your dict
doesn’t have a result key. I fixed this problem with defaultdict
and their setdefault
method.
To try it;
from collections import defaultdict
dict = defaultdict(dict)
new_result = {'key1':'new_value1','key2':'new_value2'}
dict.setdefault('result', []).append(new_result)