Search code examples
pythoncollectionsdefaultdict

Python defaultdict that does not insert missing values


So the defaultdict documentation mentions that, if an item is missing, the value returned by default_factory "is inserted in the dictionary for the key, and returned." That's great most of the time, but what I actually want in this case is for the value to be returned but not inserted into the defaultdict.

I figured I could probably subclass defaultdict and override... I guess __missing__? Not sure. What's the best way to go about this?

Thanks in advance.


Solution

  • You can subclass dict and implement __missing__:

    class missingdict(dict):
        def __missing__(self, key):
            return 'default'  # note, does *not* set self[key]
    

    Demo:

    >>> d = missingdict()
    >>> d['foo']
    'default'
    >>> d
    {}
    

    You could subclass defaultdict too, you'd get the factory handling plus copy and pickle support thrown in:

    from collections import defaultdict
    
    class missingdict(defaultdict):
        def __missing__(self, key):
            return self.default_factory() 
    

    Demo:

    >>> from collections import defaultdict
    >>> class missingdict(defaultdict):
    ...     def __missing__(self, key):
    ...         return self.default_factory() 
    ... 
    >>> d = missingdict(list)
    >>> d['foo']
    []
    >>> d
    defaultdict(<type 'list'>, {})
    

    but, as you can see, the __repr__ does lie about its name.