I create a nested defaultdict within a defaultdict which I intend to have defined key:value pairs as the default value:
from collections import defaultdict
counter_format = {"correct": 0, "incorrect": 0}
userDict = defaultdict(lambda: defaultdict(lambda: counter_format))
however, updating individual keys within the dictionary within the nested defaultdicts causes this behavior:
userDict['a'][1]['correct']+=1
userDict['b'][1]['correct']+=1
userDict['b'][2]['correct']+=1
userDict
now looks like:
defaultdict(<function <lambda> at 0x10ca85ee0>,
{'a': defaultdict(<function <lambda>.<locals>.<lambda> at 0x10cbc0430>,
{1: {'correct': 3,
'incorrect': 0}}),
'b': defaultdict(<function <lambda>.<locals>.<lambda> at 0x10cbc0b80>,
{1: {'correct': 3,
'incorrect': 0},
2: {'correct': 3,
'incorrect': 0}})})
To fix this, you simply need to move your counter_format
dictionary construction into the lambda, so that a new counter_format
dictionary is created each time you try to access a missing value in your innermost defaultdict
from collections import defaultdict
userDict = defaultdict(lambda:
defaultdict(lambda: {"correct": 0, "incorrect": 0})
)
userDict['a'][1]['correct']+=1
userDict['b'][1]['correct']+=4
userDict['b'][2]['correct']+=1
print(userdict)
defaultdict(<function <lambda> at 0x7f0f6cb38550>,
{'a': defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f0f679424c0>,
{1: {'correct': 1, 'incorrect': 0}}),
'b': defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f0f4caaa430>,
{1: {'correct': 4, 'incorrect': 0},
2: {'correct': 1, 'incorrect': 0}})})