Need python dictionary to act like deque (have maximum length)
Question:
Is there any builtin (or very simple) method of having a python dictionary work in a similar fashion as deque.
I need it to have a maximum size, and when new keys are added, if the maximum length is reached then the key added first is deleted. It shouldn’t be too difficult to implement as a custom class, but using builtins is always prefered.
I am using Python 3.6 if that is of any help.
Answers:
It sounds like you want a least recently used (LRU) cache.
The functools.lru_cache decorator might be useful to you. If you want more control, then check out the package pylru or just google Python LRU cache.
It sounds like a variant of OrderedDict
.
class FixSizeOrderedDict(OrderedDict):
def __init__(self, *args, max=0, **kwargs):
self._max = max
super().__init__(*args, **kwargs)
def __setitem__(self, key, value):
OrderedDict.__setitem__(self, key, value)
if self._max > 0:
if len(self) > self._max:
self.popitem(False)
Based on Sraw’s implementation, but updated to use the standard dict as well as avoiding keyword conflict on the max (now maxlen) parameter.
CPython 3.6 (released on Dec 23 2016) introduced insertion order in dict and from 3.7 it’s been a guarantee. No CPython version which does NOT support this behaviour is supported anymore, it’s time to update 🙂
class FixSizedDict(dict):
def __init__(self, *args, maxlen=0, **kwargs):
self._maxlen = maxlen
super().__init__(*args, **kwargs)
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
if self._maxlen > 0:
if len(self) > self._maxlen:
self.pop(next(iter(self)))
fs_dict = FixSizedDict(maxlen=2)
fs_dict['a'] = 1
fs_dict['b'] = 2
print(fs_dict)
fs_dict['c'] = 3
print(fs_dict)
Output:
{'a': 1, 'b': 2}
{'b': 2, 'c': 3}
Is there any builtin (or very simple) method of having a python dictionary work in a similar fashion as deque.
I need it to have a maximum size, and when new keys are added, if the maximum length is reached then the key added first is deleted. It shouldn’t be too difficult to implement as a custom class, but using builtins is always prefered.
I am using Python 3.6 if that is of any help.
It sounds like you want a least recently used (LRU) cache.
The functools.lru_cache decorator might be useful to you. If you want more control, then check out the package pylru or just google Python LRU cache.
It sounds like a variant of OrderedDict
.
class FixSizeOrderedDict(OrderedDict):
def __init__(self, *args, max=0, **kwargs):
self._max = max
super().__init__(*args, **kwargs)
def __setitem__(self, key, value):
OrderedDict.__setitem__(self, key, value)
if self._max > 0:
if len(self) > self._max:
self.popitem(False)
Based on Sraw’s implementation, but updated to use the standard dict as well as avoiding keyword conflict on the max (now maxlen) parameter.
CPython 3.6 (released on Dec 23 2016) introduced insertion order in dict and from 3.7 it’s been a guarantee. No CPython version which does NOT support this behaviour is supported anymore, it’s time to update 🙂
class FixSizedDict(dict):
def __init__(self, *args, maxlen=0, **kwargs):
self._maxlen = maxlen
super().__init__(*args, **kwargs)
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
if self._maxlen > 0:
if len(self) > self._maxlen:
self.pop(next(iter(self)))
fs_dict = FixSizedDict(maxlen=2)
fs_dict['a'] = 1
fs_dict['b'] = 2
print(fs_dict)
fs_dict['c'] = 3
print(fs_dict)
Output:
{'a': 1, 'b': 2}
{'b': 2, 'c': 3}