Double-Ended Queues with deque
While lists are powerful, they are inefficient when inserting or removing elements at the start. This limitation becomes visible in queue-like workflows: task schedulers, streaming buffers, undo/redo stacks, or breadth-first search algorithms in graphs.
deque is designed for precisely these scenarios, providing fast operations on both ends.
Its core methods:
deque(iterable)
deque.append(x)
deque.appendleft(x)
deque.pop()
deque.popleft()
To see this in action, consider a simple task queue:
from collections import deque
tasks = deque(["task1", "task2"])
tasks.append("task3") # add to right
tasks.appendleft("urgent") # add to left
print(tasks)Output
deque(['urgent', 'task1', 'task2', 'task3'])
You can also remove from either end efficiently:
tasks.pop() # remove "task3"
tasks.popleft() # remove "urgent"
print(tasks)Output
deque(['task1', 'task2'])
This structure excels in any scenario where both ends must remain efficient—queue systems, sliding windows, graph traversal, or managing chronological events.
In graph processing—an essential part of recommendation engines, social networks, and pathfinding—deque plays a crucial role in breadth-first search (BFS), where nodes are repeatedly removed from the front of a queue. A regular list struggles with this because removing from the front requires shifting every remaining element, whereas deque supports efficient removal from either end. The following fragment initializes a queue with a starting node:
from collections import deque
start_node = "A"
queue = deque([start_node])A full breadth-first search also needs a graph representation and a visited set. This fragment only initializes its queue; graph traversal is an extension, not a complete algorithm shown here.