'defaultdict with dict as value, but value incrementation remember the previous incrementation

I have a defaultdict with default value as a dictionary. Let's say the the default value is something like this {'A': 0, 'B': 0, 'C':0}

And every time, I put in a new key, it's going to be something like this {"Mary": {'A': 0, 'B': 0, 'C':0}}, and if I increment one the default value by one, it should be something like this {"Mary": {'A': 1, 'B': 0, 'C':0}}.

However, here is the tricky part, if I add in a new key, it's going to be something like this, {"Mary": {'A': 1, 'B': 0, 'C':0}, "Tom":{'A': 1, 'B': 0, 'C':0}}, and I wonder why? Shouldn't Tom be {'A': 0, 'B': 0, 'C':0}?

Can someone explain this to me why this is happening and how do I make sure every time I put in a new key, the initialization is going to be actually the original initialization not the newly incremented initialization? And also if I increment different letter with the same key already in the dictionary, it's going to increment as usual?

And by the way, I am doing this in a class, you guys can follow the template below:

class Tokenization: 
    def __init__(self): 
        # Let's assume I created the defaultdict here in the __init__ function

    def add_one_key(self, names, letter): 
        for name in names: 
           defaultdict[name][letter] += 1


Solution 1:[1]

You can pass a function as the default_factory parameter:

from collections import defaultdict

dct = defaultdict(lambda: {'A': 0, 'B': 0, 'C':0})

dct["Mary"]['A'] = 1
print(dct["Mary"]) # {'A': 1, 'B': 0, 'C': 0}
print(dct["Tom"])  # {'A': 0, 'B': 0, 'C': 0}

Actually when we do something like defaultdict(int), we are in fact passing function int to defaultdict. Then int() (which always returns 0) is called whenever a default value is needed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1