How to implement a lazy setdefault? How to implement a lazy setdefault? python python

How to implement a lazy setdefault?


This can be accomplished with defaultdict, too. It is instantiated with a callable which is then called when a nonexisting element is accessed.

from collections import defaultdictd = defaultdict(noisy_default)d[1] # noised[1] # no noise

The caveat with defaultdict is that the callable gets no arguments, so you can not derive the default value from the key as you could with dict.setdefault. This can be mitigated by overriding __missing__ in a subclass:

from collections import defaultdictclass defaultdict2(defaultdict):    def __missing__(self, key):        value = self.default_factory(key)        self[key] = value        return valuedef noisy_default_with_key(key):    print key    return key + 1d = defaultdict2(noisy_default_with_key)d[1] # prints 1, sets 2, returns 2d[1] # does not print anything, does not set anything, returns 2

For more information, see the collections module.


You can do that in a one-liner using a ternary operator:

value = cache[key] if key in cache else cache.setdefault(key, func(key))

If you are sure that the cache will never store falsy values, you can simplify it a little bit:

value = cache.get(key) or cache.setdefault(key, func(key))


No, evaluation of arguments happens before the call. You can implement a setdefault-like function that takes a callable as its second argument and calls it only if it is needed.