import collections
class 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] = v
d = MyDict(5)
for i in range(10):
d[i] = i
print(sorted(d))
from circular_dict import CircularDict
# Initialize a CircularDict with a maximum length of 3
my_dict = CircularDict(maxlen=3) # You could also set maxsize_bytes=8*1024 bytes
# Fill it with 4 items
my_dict['item1'] = 'value1'
my_dict['item2'] = 'value2'
my_dict['item3'] = 'value3'
# When adding this 4th item, the 1st one will be dropped
my_dict['item4'] = 'value4'
print(circ_dict)
8条答案
按热度按时间h9a6wy2h1#
Python 2.7和3.1有OrderedDict,并且有早期Python的纯Python实现。
您还必须重写其他可以插入项的方法,例如
update
。OrderedDict
的主要用途是让您可以轻松控制弹出的内容,否则普通的dict
就可以工作。slmsl1lt2#
cachetools将为您提供一个很好的Map哈希实现(它可以在python 2和3上工作)。
文件摘录:
在本模块中,缓存是固定最大大小的可变Map。当该高速缓存已满时,即通过添加另一项该高速缓存将超过其最大大小,高速缓存必须基于合适的高速缓存算法来选择丢弃哪些项。
ca1c2owp3#
这里有一个简单的,无LRU的Python 2.6+解决方案(在旧版Python中,你可以用
UserDict.DictMixin
做类似的事情,但在2.6及更高版本中,不推荐这样做,而且collections
的ABC更可取...):正如其他答案所提到的,你可能不想子类化dict --不幸的是,对
self.d
的显式委托是一个样板,但它确实保证了collections.MutableMapping
正确地提供了所有其他方法。acruukt94#
下面是一个简单而高效的LRU缓存,它是用非常简单的Python代码编写的,可以在任何Python版本1.5.2或更高版本上运行:
ni65a41a5#
已经有很多很好的答案,但我想指出一个简单的,pythonic的LRU缓存实现。这与Alex Martelli的回答相似。
ruyhziif6#
您可以通过派生dict的子类来创建自定义字典类。在您的例子中,您必须重写
__setitem__
来检查您自己的长度,并在限制被重新缓存时删除一些内容。下面的示例将在每次插入后打印当前长度:6qfn3psc7#
dict没有此行为。您可以创建自己的类来执行此操作,例如
关于这一点的几点说明
dict
是很有诱惑力的。从技术上讲,您可以做到这一点,但它容易出错,因为这些方法彼此不依赖。您可以使用UserDict.DictMixin
来保存定义所有方法。如果您子类化dict
,则可以重用的方法很少。collections.OrderedDict
,但现在,将键分别按顺序保存应该可以正常工作(使用collections.deque
作为队列)。popitem
方法删除任意一个项。gtlvzcf88#
有一个名为CircularDict的库实现了这种行为。它允许限制
dict
可以存储的最大项目量,但也可以设置内存使用限制。它可以安装有:
并以这种方式使用:
Ouptut会看起来像。