deque首尾插入删除比list快,因list是动态数组需平移元素(O(n)),而deque用双向链表实现(O(1));但中间索引访问更慢、内存开销更大,且仅适用于首尾高频操作场景。

deque 的插入删除为什么比 list 快
因为 list 是动态数组,首部插入(insert(0, x))或删除(pop(0))需要整体平移后续元素,时间复杂度是 O(n);而 deque 底层用双向链表(或分块数组)实现,首尾操作都是 O(1)。
注意:这不是“绝对快”,而是“首尾快”——中间索引访问(d[5])反而比 list 慢,且内存开销略大。别为了“听起来高级”盲目替换。
怎么初始化和常用插入删除操作
直接导入、构造,然后用 append() / appendleft() / pop() / popleft() 四个核心方法:
from collections import deque d = deque([1, 2, 3]) d.append(4) # → deque([1, 2, 3, 4]) d.appendleft(0) # → deque([0, 1, 2, 3, 4]) d.pop() # → 4,d 变成 deque([0, 1, 2, 3]) d.popleft() # → 0,d 变成 deque([1, 2, 3])
-
append()和pop()是右端(尾部),行为和list一致 -
appendleft()和popleft()是左端(头部),list没有等价的 O(1) 方法 - 初始化时传入可迭代对象(如
range、字符串、元组),但不能传单个数字(会报TypeError)
maxlen 参数的实际影响和陷阱
加 maxlen 后,deque 变成“自动截断”的固定长度队列,但行为容易误判:
立即学习“Python免费学习笔记(深入)”;
- 超过长度时,新元素从哪边进,就从**对侧**挤掉旧元素:比如
deque(maxlen=3),用append()插入,左边老元素被丢弃;用appendleft()插入,右边老元素被丢弃 -
maxlen=None(默认)表示无限制;设为 0 或负数会直接抛ValueError - 一旦设了
maxlen,再调用extendleft()或rotate()可能触发意外截断,需实测验证
示例:d = deque([1,2], maxlen=3); d.append(3); d.append(4) → 结果是 deque([2, 3, 4]),不是 [1, 3, 4]。
什么场景该用 deque,什么不该
适合:广度优先搜索(BFS)、滑动窗口求最值/均值、任务队列首尾调度、撤销/重做栈(双栈模拟)。
不适合:需要频繁按索引随机访问(比如 d[i] 循环遍历)、只在尾部操作且数据量小(此时 list 更省内存、更缓存友好)、需要保持与 list 完全兼容的 API(比如 d.sort() 不存在)。
一个常被忽略的点:多线程下 deque 的 append/popleft 是线程安全的,但 len(d) 不是原子操作——如果要判断是否为空,别写 if len(d):,改用 if d:。


















