The two simplest ways to decide what gets handled next: a queue (first in, first out) and a stack (last in, first out). Where each one shows up in real systems I have built, with examples.
The first two posts in this series were about finding things: the hash map for an exact key, binary search for ordered data. This one is about something different. It is about the order in which work gets done. Stacks and queues are the two simplest answers to one everyday question: when several things are waiting, which one do I handle next?
They sound almost too basic to matter. They are also everywhere once you start looking.
A queue is the fair one. It is the line at a bank counter. Whoever arrived first gets served first. New arrivals join at the back. We call this FIFO, first in, first out.
The two operations are simple: add to the back (enqueue), and remove from the front (dequeue).
from collections import deque
work = deque()work.append("case-101") # arrives firstwork.append("case-102")work.append("case-103")
print(work.popleft()) # case-101 (served first)print(work.popleft()) # case-102A queue is what you want whenever order and fairness matter, and nobody should jump the line.
A stack is the opposite. It is a pile of plates. You put a plate on top, and the next plate you take is the one you just put down. The most recent thing gets handled first. We call this LIFO, last in, first out.
The two operations: add to the top (push), and remove from the top (pop).
history = []history.append("opened form") # pushhistory.append("typed name")history.append("typed address")
print(history.pop()) # "typed address" (undo the most recent first)print(history.pop()) # "typed name"A stack is what you want whenever the most recent thing is the most relevant, like undo, or going back a step.
The clearest use in my work is background job processing. When a citizen submits an FIR, you do not want them staring at a spinner while the system generates a PDF, sends an SMS, and runs a few checks. So the request just drops a job onto a queue and returns immediately. A separate worker pulls jobs off the front, one by one, and does the slow work in the background.
This does two good things. It keeps the user-facing part fast, and it processes the work in a fair, predictable order. If a hundred submissions arrive at once, they line up and get handled in turn instead of overwhelming the system.
A queue is also how BFS (breadth-first search) explores. When you want the shortest path or to fan out level by level, you keep the frontier in a queue. More on that in the trees post.
The everyday one is undo. Every action gets pushed onto a stack. Hit undo, and you pop the most recent action and reverse it. The order falls out naturally because the last thing you did is exactly the first thing you want to take back.
The one you use without realising is the call stack. Every time a function calls another function, the computer pushes the current spot onto a stack so it knows where to return. When the function finishes, it pops back. This is the entire mechanism behind recursion, which is the next post in this series.
A stack also powers DFS (depth-first search), which is how you walk a document tree like the DPM ready-reckoner, going as deep down one branch as you can before backing up. And it is what checks whether brackets in code or a formula are balanced: push an opening bracket, pop on a closing one, and if the stack is empty at the end, everything matched.
list (append and pop). But for a queue, do not use list.pop(0), because removing from the front of a list is slow (it shifts everything). Use collections.deque and popleft, which is fast. This small choice has bitten many people.Three structures, three different jobs now. The hash map answers “where is this exact thing.” Binary search answers “where does this fall in sorted data.” Stacks and queues answer “what do I do next,” either the oldest waiting item or the newest.
And here is the nice thread into the next post: the call stack that runs every function is itself a stack. Which means recursion, the thing that scares a lot of people, is really just a stack you do not have to manage yourself.
Next in this series: recursion and trees, and why a problem that contains smaller copies of itself is easier than it looks.