Fast queues with deque

collections · Essentials · 8 min

Queues, BFS, undo history and 'last N items' buffers all need cheap operations at both ends.

A list is fast at its end but slow at its start: lst.pop(0) and lst.insert(0, x) shift every element, which is O(n). A deque ("deck", double-ended queue) supports fast operations at both ends:

  • append(x) and appendleft(x)
  • pop() and popleft()
  • extend(iterable) and extendleft(iterable) (which reverses the order)

That makes it the right structure for a FIFO queue: append to enqueue, popleft to dequeue.

With maxlen, a deque is a bounded buffer: deque(maxlen=3) keeps only the last three items, automatically discarding from the opposite end when you append. It's ideal for "the last N log lines" or a moving window.

A deque supports len, iteration, in, indexing (d[0], d[-1]) and clear. Indexing near the ends is fast, but access in the middle is O(n), and slicing isn't supported. If you need random access more than end operations, stay with a list.

Popping from an empty deque raises IndexError; check if d: first.

For queues shared between threads, use queue.Queue, which adds blocking get and put with timeouts; for asyncio, asyncio.Queue.

Example

from collections import deque

tasks = deque(["a", "b"])
tasks.append("c")              # enqueue at the right
tasks.appendleft("urgent")     # jump the queue
print(tasks.popleft())         # urgent
print(list(tasks))             # ['a', 'b', 'c']

recent = deque(maxlen=3)
for line in ["l1", "l2", "l3", "l4", "l5"]:
    recent.append(line)
print(list(recent))            # ['l3', 'l4', 'l5']
print(recent[0], recent[-1])   # l3 l5

d = deque()
d.extendleft([1, 2, 3])
print(d)                       # deque([3, 2, 1])

Remember

  • deque appends and pops at both ends in O(1)
  • maxlen keeps only the most recent N items
  • Use queue.Queue for producer/consumer queues between threads

Watch out for

  • Using list.pop(0) as a queue on large lists, which is O(n) per pop.

Check yourself

  1. d = deque([1, 2, 3], maxlen=3); d.appendleft(0). What is d?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/collections.html#collections.deque