Lists, Tuples & Sets
You've been using lists since Lesson 5. Now meet all three of Python's built-in collections — lists, tuples, and sets — and learn when each one fits. This lesson builds the app's order list: the distinct dishes a table ordered.
Every box is live — edit and ▶ Run.
Part 1 — Lists: ordered and changeable
A list holds items in order, in square brackets [ ]. It's the workhorse
collection — use it whenever order matters and the contents may change:
Lists are mutable — you can change them after creating them:
Slicing grabs a range ([start:stop], stop not included):
Part 2 — Tuples: ordered and fixed
A tuple is like a list but immutable — once made, it can't change. Use a tuple for a fixed group of values that belong together (a coordinate, an RGB colour, a row):
Try to change it and Python stops you:
A handy trick is unpacking — pull a tuple's values into separate variables in one line:
Part 3 — Sets: unordered and unique
A set holds unique items with no order, in curly braces { }.
Duplicates simply vanish — which makes sets perfect for "give me the distinct
values":
❓ Cross-question — "Is a Python
setlike a JSSet?" Behaviour-wise yes (unique items, fastin). Two catches: the literal{}is an empty dict, not a set — an empty set must beset(). And set items must be hashable (immutable), whereas a JSSetcan hold any object by reference.
Removing from a set: .remove() vs .discard()
Two methods that look interchangeable and are not. .remove() raises if the item
isn't there; .discard() shrugs:
KeyErrorRun it and meet KeyError. Then make it print the two orders without crashing.
Reach for .discard() when "it might not be there" is normal, and .remove()
when its absence means something has already gone wrong and you'd rather hear
about it.
Sets also do maths — union |, intersection &, difference -:
Which do I pick? Ordered list you'll change → list. Fixed group that shouldn't change → tuple. Just need the unique values / fast membership → set.
Part 4 — Combine them: unique, then sorted
Sets lose duplicates but also lose order. sorted(...) takes any collection and
returns a tidy list in order. Chain them and you get "unique and sorted":
That single expression is exactly the task below.
Part 5 — Idioms & real-world patterns
The three collections have sharp edges that trip up developers from every other language. Slow down here — especially on copying.
Assignment shares — it does NOT copy
b = a does not make a second list. Both names point at the same list, so
a change through one is visible through the other:
a = [1, 2, 3]
b = a
b.append(4)
print(len(a))Step through it. Watch a change on the line that only mentions b — that's the
whole lesson in one frame:
Coming from Java/JS: exactly like assigning an array/object reference — you copied the reference, not the data. Ints and strings only feel like copies because they're immutable.
❓ Cross-question — "So
b = ais a reference copy, like JS objects/arrays?" Exactly — assignment never copies a list/dict/set; both names bind the same object (a is b). Numbers, strings, and tuples only look copied because they're immutable, so you can't observe the sharing. To truly copy, use.copy()/deepcopybelow.
is vs == — identity vs value
== asks "same value?"; is asks "the same object?" Use == to compare,
and is only for None:
Coming from Java:
==here is.equals();isis Java's==(reference identity). From JS:==≈ value check,is≈===on object identity.
Shallow copy — a real (but one-level) copy
To actually duplicate a list, use .copy(), list(...), or a full slice [:]:
⚡ Deep copy — copies all the way down
A shallow copy duplicates the outer list but still shares the inner
objects. With nested data that's a classic bug — copy.deepcopy fixes it:
Coming from JS:
cart.copy()is[...cart]/Object.assign(one level);copy.deepcopy(cart)isstructuredClone(cart).
.extend vs +, and the other methods
Extended unpacking — a, *rest
Grab the first (or last) item and collect the rest with a starred name:
Sets: comprehensions, frozenset, and subset math
⚡ Advanced — hashability: why a list can't be a set item or dict key
Sets and dict keys must be hashable — which in practice means immutable. Tuples of immutables qualify; lists never do:
Coming from Java: same reason a mutable object makes a bad
HashMapkey — if it changes, its hash changes and the map breaks. Python refuses it up front.
❓ Cross-question — "Why can JS put any object in a
Set/Mapbut Python can't?" JS keys by reference identity; Python keys by value hash, which requires the element be immutable (str,int,tuple,frozenset). That's why alistcan't live in a set or be a dict key — its contents (and hash) could change under the collection.
⚡ Advanced — namedtuple: a tuple with named fields
When a tuple's positions start to blur, give them names (a lightweight, immutable record — the step before a full dataclass):
🎯 Your turn
Write unique_dishes(orders) — it takes a list of dish names (with duplicates) and
returns a sorted list of the unique names:
unique_dishes(["soup", "steak", "soup", "salad"])→["salad", "soup", "steak"]unique_dishes([])→[]
Hint — set(orders) drops the duplicates, and sorted(...) gives back an
ordered list. Together: sorted(set(orders)).
Then press ▶ Run, tap the Live App try chips to call it with different orders, and hit ✓ Check. Green = this piece of the app is built. ✅
