Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Last in or first in (stacks and queues)

After this lesson: I can use a stack and a queue.

45 min lesson2 commandsJupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

The undo button and the print queue

You press undo in an essay and the last thing you typed disappears, not the first. You send three pages to a school printer and they come out in the order you sent them.

Those are two different rules for taking things out. Each one is a data structure every programmer uses.

By the end of this lesson

Note

I can use a stack and a queue.

Key words

WordWhat it means
Stacka pile where the last item in is the first out
Queuea line where the first item in is the first out
Pushto put an item on top of a stack
Popto take the top item off a stack
LIFOlast in, first out: how a stack works
FIFOfirst in, first out: how a queue works

The cells students fill in are left blank in this preview.

A stack takes from the top

A stack is like a pile of plates. You push a plate on top, and you pop the top one off. You never take from the middle.

In Python a list works as a stack. append pushes onto the end, and pop() takes the last item. Undo, the back button and a game's menus all use one.

An undo stack

Code: python
# An undo button: each change is pushed on a stack.
undo = []
undo.append("typed Hello")
undo.append("made it bold")
undo.append("added a picture")
print("stack:", undo)
last = undo.pop()
print("undo takes back:", last)
print("stack now:", undo)
# Push "changed the colour", then pop twice.
# Which two changes come back, and in what order?

A queue serves from the front

A queue is like the line at a till. People join at the back and are served from the front, so the first to arrive is the first served.

A list can act as a queue: append joins at the back and pop(0) serves the front. Print jobs, game lobbies and messages all wait in queues.

A queue at a till

Code: python
# A queue at a cafe till: join at the back, serve from the front.
queue = []
queue.append("Amir")
queue.append("Beth")
queue.append("Chen")
print("queue:", queue)
served = queue.pop(0)
print("served first:", served)
print("still waiting:", queue)
# Add "Dana" to the queue, then serve two more people.
# Who is left waiting?

A common mistake

Warning

Many people use pop() for a queue. With no number, pop() takes the last item, so the newest person is served first. A queue needs pop(0), or better a deque with popleft(), because the front must leave first.

A faster queue in the lab

When a list serves its front with pop(0), every other item shuffles forward one place. That is O(n), and a long queue makes it slow.

Python's deque is built for queues. Its popleft is O(1). The Runs time one join and one serve on a queue of 100,000, first with a list and then with a deque.

Time a list as a queue

Command
docker exec jupyter python3 -m timeit -s "q = list(range(100000))" "q.append(0)" "q.pop(0)"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Time a deque as a queue

Command
docker exec jupyter python3 -m timeit -s "from collections import deque" -s "q = deque(range(100000))" "q.append(0)" "q.popleft()"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Type this in your notebook: a till queue

Code: python
from collections import deque

# Orders at a till, served in the order they arrive.
orders = deque()
orders.append("cheese toastie")
orders.append("hot chocolate")
orders.append("flapjack")
print("first out:", orders.popleft())
print("waiting:", list(orders))

A stack checks brackets

Code editors check that every bracket closes. They use a stack. Read the text from left to right.

Push each opening bracket. At each closing bracket, pop the top one: it must be the same kind. At the end the stack must be empty. A wrong pop, or a pop from an empty stack, means a mistake.

Worked example: checking f(a[1])

ReadWhat happensStack after
fNot a bracket: skip itempty
(Push it(
aSkip it(
[Push it( [
1Skip it( [
]Pop [: it matches(
)Pop (: it matchesempty
EndThe stack is empty: balancedempty

The cells students fill in are left blank in this preview.

Going further: a stack from two queues

Could you make a stack using only queues? Try it in your notebook with two deques and only append and popleft.

Push 1, 2 and 3, then pop. You should get 3. Which operation becomes slow, and is it O(1) or O(n)?

About this lab and its source: JupyterLab data science lab: pandas, Matplotlib and scikit-learn in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.