Python code using list as a queue or deque, calling list.pop(0) or list.insert(0, x) for FIFO operations. The metric was operation throughput. list.pop(0) is O(N) because it shifts all remaining elements left in memory, making list-based queues quadratic for N operations.
Replacing list with collections.deque for any use case requiring efficient insertion/removal at both ends. deque is implemented as a doubly-linked list of fixed-size blocks, providing O(1) append, appendleft, pop, and popleft.
For a BFS traversal processing 5M nodes, switching from list.pop(0) to deque.popleft() reduced time from 42s to 1.2s (35x speedup).
| Operation | list | deque | Speedup |
|---|---|---|---|
| Append right (1M ops) | 52ms | 48ms | 1.1x |
| Pop right (1M ops) | 51ms | 47ms | 1.1x |
| Pop left (1M ops) | 12,400ms | 47ms | 264x |
| Insert left (1M ops) | 13,100ms | 48ms | 273x |
| Random access [i] | 0.05μs | 0.3μs | 0.17x (list wins) |
from collections import deque
# BAD: list as queue — O(N) per popleft
queue = []
queue.append(start_node)
while queue:
node = queue.pop(0) # O(N) — shifts all elements
for neighbor in node.adj:
queue.append(neighbor)
# GOOD: deque as queue — O(1) per popleft
queue = deque()
queue.append(start_node)
while queue:
node = queue.popleft() # O(1) — no shifting
for neighbor in node.adj:
queue.append(neighbor)
# Bounded deque for sliding window / recent history
recent = deque(maxlen=1000) # automatically discards oldest when full
for event in stream:
recent.append(event) # O(1), old events auto-evicted
# deque also supports rotate() for circular buffer patterns
d = deque([1, 2, 3, 4, 5])
d.rotate(2) # [4, 5, 1, 2, 3] — O(k) rotation- deque for random access:
deque[i]is O(N) (walks the block chain), whilelist[i]is O(1). If you need both fast random access and fast left insertion, considersortedcontainers.SortedListor a different data structure. - deque for slicing:
dequedoesn't support slicing (d[1:5]). Convert to list first if needed.
CPython 3.8+. collections.deque is a C extension in the stdlib. For thread-safe queues, use queue.Queue (which wraps deque with locks).