pythonpython-3.xdictionarydefaultdictpython-collections

`dict.pop` ignores the default value set by `collections.defaultdict(default_factory)`


Python's dict.pop(key[, default]) ignores the default value set by collections.defaultdict(default_factory) as shown by the following code snippet:

from collections import defaultdict

d = defaultdict(lambda: 1)
d['a']
d['b'] = 2
print(d.pop('a')) # 1
print(d.pop('b')) # 2
print(d.pop('c', 3)) # 3
d.pop('e') # KeyError: 'e'

d is a defaultdict(lambda: 1). d.pop('e') causes a KeyError. Is this intended? Shouldn't d.pop('e') return 1 since that's the default value set by defaultdict?


Solution

  • TL;DR: In summary, defaultDict will make dict['inexistent-key'] return your default value, anythying else should have the same behaviour as a normal dict.

    Explanation

    The documentation you linked states that:

    It overrides one method [__missing__()] and adds one writable instance variable [default_factory]. The remaining functionality is the same as for the dict class and is not documented here.

    That is further specified under the __missing__() method itself, which is called by __getitem__() on a dict:

    Note that __missing__() is not called for any operations besides __getitem__(). This means that get() will, like normal dictionaries, return None as a default rather than using default_factory.

    So not only pop() will have the same behaviour, get() will too. The only way to have the default value would be to straight up use [key] on your dict. And if we think about it, it's definitely the most relevant call on a dict.