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

为什么 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
真正麻烦的不是结构,而是每次 get 和 put 都得小心处理「是否已存在」「容量是否为 0」「删谁才对」——这些逻辑一旦漏判,缓存行为就不可预测。










