Python 的 deque:比 list 快 100 倍的神奇列表(队列)

python 中,list 是最常用的数据结构之一。当需要频繁在头部或尾部插入、删除元素时,list 可能会变得很慢。

这时候,collections.deque(双端队列)就该使用这个了deque 。 在某些操作上,它甚至比 list 快 100 倍!

 

1. 什么是 deque?

deque(发音 "deck")是 双端队列(Double-Ended Queue) 的缩写。它允许你从两端高效地添加或删除元素,时间复杂度仅为 O(1)

而 list 在头部操作时,时间复杂度是 O(n),因为它需要移动所有元素。这就是为什么 deque 在特定场景下比 list 快得多!

deque 的基本用法

from collections import deque

# 创建一个 deque
d = deque([1, 2, 3])  # deque([1, 2, 3])

# 从右侧添加元素
d.append(4)  # deque([1, 2, 3, 4])

# 从左侧添加元素
d.appendleft(0)  # deque([0, 1, 2, 3, 4])

# 从右侧弹出元素
d.pop()  # deque([0, 1, 2, 3])

# 从左侧弹出元素
d.popleft()  # deque([1, 2, 3])

  

2. deque vs list:性能对比

测试 1:头部插入(appendleft 和 insert(0, x)

import timeit


# 测试 deque 的 appendleft
def test_deque_appendleft():
    d = deque()
    for i in range(10000):
        d.appendleft(i)


# 测试 list 的 insert(0, x)
def test_list_insert():
    lst = []
    for i in range(10000):
        lst.insert(0, i)


# 测量时间
deque_time = timeit.timeit(test_deque_appendleft, number=1000)
list_time = timeit.timeit(test_list_insert, number=1000)

print(f"deque.appendleft:{deque_time:.4f}秒")  # 输出:0.4435秒
print(f"list.insert(0, x):{list_time:.4f}秒")  # 输出:14.7492秒

  

测试 2:头部删除(popleft 和 pop(0)

from collections import deque
import timeit


def test_deque_popleft():
    d = deque(range(10000))
    for _ in range(10000):
        d.popleft()


def test_list_pop0():
    lst = list(range(10000))
    for _ in range(10000):
        lst.pop(0)


deque_time = timeit.timeit(test_deque_popleft, number=1000)
list_time = timeit.timeit(test_list_pop0, number=1000)

print(f"deque.popleft:{deque_time:.4f}秒")  # 输出:0.5152秒
print(f"list.pop(0):{list_time:.4f}秒")  # 输出:5.7043秒

  

3. deque 的进阶用法

(1) 限制队列长度(maxlen)

deque 可以设置最大长度,当队列满时,新元素加入会自动丢弃另一端的元素。

from collections import deque

d = deque(maxlen=3)
d.append(1)  # deque([1])
d.append(2)  # deque([1, 2])
d.append(3)  # deque([1, 2, 3])
d.append(4)  # deque([2, 3, 4]),最左边的 1 被丢弃

适用场景:

  •  滑动窗口计算
  • 最近 N 条记录存储

  

(2) 旋转队列(rotate)

rotate(n) 可以让队列循环移动:

  • rotate(1):向右移动 1 位
  • rotate(-1):向左移动 1 位
from collections import deque

d = deque([1, 2, 3, 4, 5])
d.rotate(2)  # deque([4, 5, 1, 2, 3])
d.rotate(-1)  # deque([5, 1, 2, 3, 4])

适用场景:

  • 轮播数据
  • 循环缓冲区

 

(3) 线程安全(可用于多线程队列)

deque 的 appendpop 等操作是线程安全的,适合用于多线程任务队列。

from threading import Thread
from collections import deque
import time

queue = deque()


def producer():
    for i in range(5):
        queue.append(i) 
        time.sleep(0.1)


def consumer():
    while True:
        if queue:
            print(queue.popleft())
        time.sleep(0.1)


Thread(target=producer).start()
Thread(target=consumer).start()

  

4. 什么时候用 deque?什么时候用 list

操作 deque 效率 list 效率 推荐选择
头部插入/删除 ⚡ O(1) 🐢 O(n)
 deque尾部插入/删除 ⚡ O(1) ⚡ O(1) 都可以
随机访问 🐢 O(n) ⚡ O(1) ✅ list


 

 

 

总结:

  • 如果需要频繁在头部操作(如队列、栈),用 deque
  • 如果需要随机访问元素(如 lst[1000]),用 list

deque 是 Python 中一个被低估的高性能数据结构。
在需要高效头部操作的场景下,它比 list 快 100 倍
适用于:
✅ 队列(FIFO)
✅ 栈(LIFO)
✅ 滑动窗口计算
✅ 线程安全任务队列

如果的代码涉及大量 insert(0, x) 或 pop(0),就换成 deque 

 

posted @ 2025-08-01 17:37  北京测试菜鸟  阅读(66)  评论(0)    收藏  举报