How to limit the size of a dictionary?
Python 2.7 and 3.1 have OrderedDict and there are pure-Python implementations for earlier Pythons.
from collections import OrderedDictclass LimitedSizeDict(OrderedDict): def __init__(self, *args, **kwds): self.size_limit = kwds.pop("size_limit", None) OrderedDict.__init__(self, *args, **kwds) self._check_size_limit() def __setitem__(self, key, value): OrderedDict.__setitem__(self, key, value) self._check_size_limit() def _check_size_limit(self): if self.size_limit is not None: while len(self) > self.size_limit: self.popitem(last=False)
You would also have to override other methods that can insert items, such as update
. The primary use of OrderedDict
is so you can control what gets popped easily, otherwise a normal dict
would work.
cachetools will provide you nice implementation of Mapping Hashes that does this (and it works on python 2 and 3).
Excerpt of the documentation:
For the purpose of this module, a cache is a mutable mapping of a fixed maximum size. When the cache is full, i.e. by adding another item the cache would exceed its maximum size, the cache must choose which item(s) to discard based on a suitable cache algorithm.
Here's a simple, no-LRU Python 2.6+ solution (in older Pythons you could do something similar with UserDict.DictMixin
, but in 2.6 and better that's not recommended, and the ABCs from collections
are preferable anyway...):
import collectionsclass MyDict(collections.MutableMapping): def __init__(self, maxlen, *a, **k): self.maxlen = maxlen self.d = dict(*a, **k) while len(self) > maxlen: self.popitem() def __iter__(self): return iter(self.d) def __len__(self): return len(self.d) def __getitem__(self, k): return self.d[k] def __delitem__(self, k): del self.d[k] def __setitem__(self, k, v): if k not in self and len(self) == self.maxlen: self.popitem() self.d[k] = vd = MyDict(5)for i in range(10): d[i] = i print(sorted(d))
As other answers mentioned, you probably don't want to subclass dict -- the explicit delegation to self.d
is unfortunately boilerplatey but it does guarantee that every other method is properly supplied by collections.MutableMapping
.