感谢这位博主解答,搞了很久才弄明白这个问题
https://blog.youkuaiyun.com/qq_35810838/article/details/83035759
# 思路:用列表保存数据的顺序,列表中数据越靠后,表示最新访问,更新时间越晚
# 最旧数据的key---->最新数据的key
# [data1,data2,data3,data4,...,]
# 完整数据
# {data1:xxx,data2:xxx,data3:xxx,data4:xxx}
'''
# 基于列表&字典实现
class LRU:
def __init__(self,capacity):
# 保存数据的key&value
self.cache = {}
# 保存数据key,用来排序
self.used_list = []
# 限制数据最大条数
self.capacity = capacity
#使用一个list来记录数据访问的顺序,最先访问的数据放在list的前面,最后访问的数据放在list的后面,所以存储的数据量(capacity)达到上限时,则删除排序表中最先访问(最旧的)的数据list[0],然后插入新项;
def get(self,key):
# 如果访问的数据在缓存列表中,代表曾经访问过该数据
if key in self.cache:
# 判断这个访问的数据是不是最近一次访问过的,如果不是,就把数据提到列表最后(即最新访问元素的位置),即删除原有记录,再把数据当成最新访问的添加到列表最后
if key != self.used_list[-1]:
# 把上一次访问过的该数据清除
self.used_list.remove(key)
# 把当前访问的数据追加到列表最后
self.used_list.append(key)
# 修改cache中的数据并返回一个修改过的真实数据值
return self.cache[key]
else:
# 如果未访问过该条数据,将调用set方法,更新排序列表used_list并更新cache字典完整数据(删除最旧的,添加当前访问这条最新的数据),并返回最新添加的数据的值
return self.set()
def set(self,key,value):
# 判断数据库要求储存的数据是否达到上限,如果达到上限,删除排序列表中的第一位(最旧的数据的key)并且删除cache中对应的最旧的数据键值对
if len(self.cache) == self.capacity:
self.cache.pop(self.used_list.pop(0))
# 然后把当前访问的数据(最新)的key添加到列表,最新数据键值对添加到cache字典中
self.used_list.append(key)
self.cache[key] = value
return value
'''
import collections
#基于orderedDict实现
class LRUCache(collections.OrderedDict):
'''
利用OrdereDict特殊的方法popitem(Last=False)时则实现队列,弹出最先(最旧)插入的元素
而当Last=True则实现堆栈方法,弹出的是最近(最新)插入的那个元素。
实现了两个方法:get(key)取出键中对应的值,若没有返回None
set(key,value)更具LRU特性添加元素
'''
def __init__(self,size=5):
self.size = size
self.cache = collections.OrderedDict()#创建一个空的有序字典
def get(self,key):
if key in self.cache.keys():
# 删除并获取到当前访问的数据的value
value = self.cache.pop(key)
# 重新添加键值对来实现orderdict中当前数据设为最近(最新)插入元素
self.cache[key] = value
# 返回最新访问的数据
return value
else:
# 如果未访问过该条数据,将调用set方法,更新orderdict数据(删除最旧的,添加当前访问这条最新的数据),并返回最新添加的数据的值
return set()
def set(self,key,value):
# 判断数据库要求储存的数据是否达到上限,如果达到上限,删除orderdict中最旧的键值对,添加最新数据为键值对
if self.size == len(self.cache):
self.cache.popitem(last=False)
self.cache[key] = value
else:
self.cache[key] = value```