Python 如何在不使用第三方库的情况下实现简单的 LRU 缓存

7次阅读

python 3.7+ dict 插入顺序可直接模拟LRU:get时pop再重设以置末尾,put时若满则删next(iter(dict))获取的首个key,配合capacity控制实现O(1)操作。

Python 如何在不使用第三方库的情况下实现简单的 LRU 缓存

为什么 dict 的插入顺序能当 LRU 用

Python 3.7+ 的 dict 保证插入顺序,这意味着你可以把最常访问的 key 放在最后,淘汰时直接删第一个——这正好符合 LRU「最近最少使用」的逻辑。不需要额外维护时间戳或链表,靠字典本身的有序性就能模拟出 LRU 行为。

注意:Python 3.6 在 CPython 实现中也保持顺序,但语言规范未保证;生产环境请确认版本 ≥3.7。

手动实现 LRUCache 类的关键操作

核心是三个动作:读(get)、写(put)、淘汰(容量超限时删最早插入项)。所有操作都围绕一个 dict 展开,不引入 collections.OrderedDict 或其他模块。

  • get:如果 key 存在,先 pop 它再重新 set(即删掉再插到末尾),确保它变成「最近使用」
  • put:如果 key 已存在,同样先 pop 再重设;如果不存在且容量满,用 next(iter(cache)) 拿到第一个 key 并删除
  • 用普通 dict 存数据,用整数变量 self.capacity 控制上限

容易忽略的边界情况和坑

实际写的时候,这几个点最容易出错:

立即学习Python免费学习笔记(深入)”;

  • 容量为 0 时,put 应该直接返回,不存任何值(否则后续 get 永远为空)
  • get 找不到 key 时必须返回 -1(按经典 LRU 题约定),不能返回 None 或抛异常
  • 重复 put 同一个 key 时,要更新 value 并「刷新位置」,不是跳过操作
  • 判断容量是否超限,要在插入新 key 检查:if len(self.cache) >= self.capacity and key not in self.cache:

一个可直接跑的最小可用示例

下面这段代码不含任何 import,只用内置类型,在 Python 3.7+ 上可直接运行:

class LRUCache:     def __init__(self, capacity: int):         self.capacity = capacity         self.cache = {} 
def get(self, key: int) -> int:     if key not in self.cache:         return -1     # 刷新访问顺序:取出再放回末尾     value = self.cache.pop(key)     self.cache[key] = value     return value  def put(self, key: int, value: int) -> None:     if key in self.cache:         self.cache.pop(key)     elif len(self.cache) >= self.capacity > 0:         # 删除第一个(最久未用)         oldest_key = next(iter(self.cache))         self.cache.pop(oldest_key)     if self.capacity > 0:         self.cache[key] = value

真正麻烦的不是结构,而是每次 getput 都得小心处理「是否已存在」「容量是否为 0」「删谁才对」——这些逻辑一旦漏判,缓存行为就不可预测。

text=ZqhQzanResources