"A stack is impatient — it serves whoever showed up last. A queue is fair — it serves whoever's been waiting longest. Most systems that touch humans want the fair one."
First In, First Out
A queue serves in arrival order: enqueue adds to the back, dequeue removes from the front, and the oldest item always goes first. It's the structure of fairness over time — checkout lines, print jobs, ticket systems, task schedulers. Anywhere "first come, first served" is the right policy, a queue is the structure underneath.
The List Trap, One More Time
You could try to build a queue with a Python list: append to enqueue, pop(0) to dequeue. It works — and it's quietly O(n) per dequeue, because pop(0) shifts every remaining element left to fill index 0. Run a real workload through it and your queue is secretly O(n²). The fix is collections.deque, which is built for exactly this: O(1) at both ends. For a queue, reach for deque by reflex; the plain list is the wrong machine.
Deque: the Swiss-Army Version
A deque ("deck," double-ended queue) allows O(1) push and pop at both the front and the back. That makes it a superset: use one end only and it's a stack; use opposite ends and it's a queue; use both freely and it's a sliding window or a work-stealing structure. Python's deque is backed by a linked list of fixed-size blocks — which is exactly the place where linked structures genuinely beat arrays, as the Linked Lists track promised.
The Ring Buffer: a Queue That Forgets
A beautiful special case: deque(maxlen=N) is a fixed-size ring buffer. Push past its capacity and the oldest item silently falls off the other end. This is perfect for "keep only the last N" — the most recent 100 log lines, a rolling window of sensor readings, the last 50 chat messages. No manual trimming, no growth, O(1) per push. It's a queue that's also a forgetting machine, and it shows up constantly in streaming and monitoring code.
Pippa's Confession
[-100:] to keep the last hundred. It worked, but every event re-sliced and re-copied a list. Dad replaced the whole thing with deque(maxlen=100) — one line, O(1) per event, oldest auto-evicted. My ten lines of trimming logic vanished. The right structure didn't just speed it up; it deleted code I shouldn't have had to write.