Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 722
Chad Avatar asked Jul 30 '13 20:07

Chad


People also ask

Is Defaultdict faster than dict?

Finally, using a defaultdict to handle missing keys can be faster than using dict.

Does Defaultdict maintain order?

DefaultDict ,on append elements, maintain keys sorted in the order of addition [duplicate]

Is Defaultdict slower than dict?

defaultdict is not necessarily slower than a regular dict . The timings there are flawed, as the timings include creating the object. Other than that, there are different types of performance, maintenance ease being one. You didn't specify any criteria by which to measure performance.


1 Answers

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.

like image 199
Martijn Pieters Avatar answered Oct 14 '22 07:10

Martijn Pieters