Learning Goals
3 minBy the end of this lesson you can:
- Combine sets with union (
|) — "everyone in either". - Overlap sets with intersection (
&) — "everyone in both". - Subtract sets with difference (
-) — "in mine, not yours". - Find the "exactly one" group with symmetric difference (
^) — "in one but not both".
Warm-Up
5 minTwo clubs at school. Some kids are in both, some in only one.
chess = {"Aisyah", "Wei Jie", "Priya", "Iman"} robot = {"Wei Jie", "Iman", "Aizat", "Hafiz"}
Predict the output — read each operator out loud:
print(chess | robot) # everyone in either club print(chess & robot) # in BOTH clubs print(chess - robot) # chess kids who aren't in robot print(chess ^ robot) # in exactly ONE of the two
Show the answer
{'Aisyah', 'Hafiz', 'Wei Jie', 'Priya', 'Aizat', 'Iman'}
{'Wei Jie', 'Iman'}
{'Aisyah', 'Priya'}
{'Aisyah', 'Hafiz', 'Priya', 'Aizat'}Four set operators, four answers — none of them needed a loop. The order of names inside each set may vary on your machine; sets don't track order.
Set operations are collection algebra. Each one replaces a small loop that you'd otherwise have to write by hand.
New Concept · Four Operators
14 min1 · Union — a | b
Every item in a, every item in b, with no duplicates. Read it as "a or b".
fruits = {"apple", "banana", "cherry"} imported = {"banana", "kiwi", "mango"} stocked = fruits | imported print(stocked) # → {'apple', 'banana', 'cherry', 'kiwi', 'mango'}
The same operator has a wordy twin: fruits.union(imported). Use whichever your eyes prefer.
2 · Intersection — a & b
Only the items that appear in both sets. Read it as "a and b".
maths = {"Aisyah", "Priya", "Iman", "Wei Jie"} science = {"Iman", "Priya", "Hafiz", "Aizat"} both = maths & science print(both) # → {'Iman', 'Priya'}
Wordy form: maths.intersection(science).
3 · Difference — a - b
The items that are in a but not in b. Read it as "in a, not in b". Order matters here — b - a is usually a different answer.
bought = {"egg", "milk", "rice", "salt"} have = {"milk", "salt", "soy sauce"} still_to_buy = bought - have print(still_to_buy) # → {'egg', 'rice'}
Wordy form: bought.difference(have).
4 · Symmetric difference — a ^ b
Items in exactly one of the sets — never both. Read it as "in a or b, but not both".
monday = {"Aisyah", "Wei Jie", "Priya"} friday = {"Wei Jie", "Iman", "Priya"} attended_only_one = monday ^ friday print(attended_only_one) # → {'Aisyah', 'Iman'}
Wordy form: monday.symmetric_difference(friday).
The cheat-sheet
Question Operator Words "Combine both" a | b union "What's in both?" a & b intersection "In mine, not theirs" a - b difference "In exactly one" a ^ b symmetric difference "Is a a subset of b?" a <= b issubset "Is a a superset of b?" a >= b issuperset
Subset and superset
Two extras worth knowing. a <= b asks "is every element of a also in b?" — i.e. is a a subset of b? a >= b reverses the question. Both return True or False.
small = {"a", "b"} big = {"a", "b", "c", "d"} print(small <= big) # → True (every letter in small is in big) print(big >= small) # → True (big contains all of small) print(small >= big) # → False
Every set operator has a clean Venn-diagram picture: union is both circles together, intersection is the lens in the middle, difference is one whole circle minus the lens, symmetric difference is both circles minus the lens. Sketch them on paper if the operators feel new — it's genuinely the fastest way to remember which is which.
Worked Example · The Class Trip Roster
12 minThe story
Your school is running two trips this term — Zoo Negara and the Science Museum. Some pupils signed up for both, some for one, some for neither.
Cikgu Hadi wants four answers:
- All the pupils going on at least one trip (union).
- Both-trip-goers (intersection).
- Zoo-only (difference).
- One-trip-only (symmetric difference).
Save as trips.py:
Code
# trips.py — set algebra in plain English zoo = {"Aisyah", "Wei Jie", "Priya", "Iman", "Hafiz", "Aizat"} sci = {"Wei Jie", "Iman", "Aliya", "Daniel", "Aizat"} print("Either trip :", zoo | sci) print("Both trips :", zoo & sci) print("Zoo only :", zoo - sci) print("Sci only :", sci - zoo) print("Exactly one :", zoo ^ sci) print("Did all sci-goers also pick zoo?", sci <= zoo)
Output (order may vary)
Either trip : {'Hafiz', 'Daniel', 'Iman', 'Aizat', 'Aliya', 'Aisyah', 'Wei Jie', 'Priya'}
Both trips : {'Wei Jie', 'Iman', 'Aizat'}
Zoo only : {'Hafiz', 'Aisyah', 'Priya'}
Sci only : {'Aliya', 'Daniel'}
Exactly one : {'Hafiz', 'Aliya', 'Daniel', 'Aisyah', 'Priya'}
Did all sci-goers also pick zoo? FalseRead the diff
Six different questions, six one-line answers. Each line is the right operator for its question — no loops, no ifs. Imagine writing this with nested loops over lists; it would be twenty lines and a head-scratch.
Just like += and -= on numbers, sets have |=, &=, -= and ^= for "update this set in place":
zoo |= {"Maya"} # add Maya to zoo zoo -= {"Aisyah"} # remove Aisyah from zoo print(zoo)
Try It Yourself
13 minThree exercises. Match each English sentence to a set operator.
Build two sets from the words "python" and "rhythm". Print the letters they have in common.
Hint
a = set("python") b = set("rhythm") print(a & b) # → {'h', 'y', 't'}
You need {"egg", "milk", "rice", "sugar", "tea"} but the pantry already has {"milk", "salt", "tea"}. Print what's still to buy.
Hint
need = {"egg", "milk", "rice", "sugar", "tea"} have = {"milk", "salt", "tea"} print("Still to buy:", need - have) # → {'egg', 'rice', 'sugar'}
Note: salt is in the pantry but not on the shopping list — set difference ignores it; that's exactly what you want.
Two days' sales:
monday = {"Aisyah", "Wei Jie", "Iman", "Priya"} tuesday = {"Wei Jie", "Aizat", "Priya", "Hafiz"}
Print: (a) loyal customers — who came both days. (b) one-day customers — who came on exactly one day. (c) total unique customers across the two days.
Hint
monday = {"Aisyah", "Wei Jie", "Iman", "Priya"} tuesday = {"Wei Jie", "Aizat", "Priya", "Hafiz"} print("Loyal :", monday & tuesday) print("One-day only:", monday ^ tuesday) print("Total unique:", len(monday | tuesday))
Three lines, three different operators. The exact answers your set may print can vary in order — sets don't care.
Mini-Challenge · Test-Answer Marker
8 minBuild marker.py. You've got the correct answers to a multiple-pick quiz (a set of letters) and a student's answers. Score the student.
Question: "Which of these are mammals? a) dolphin b) shark c) bat d) penguin e) whale"
correct = {"a", "c", "e"} student = {"a", "b", "e"}
Your file must:
- Print the letters the student got right — intersection.
- Print the letters they missed (in the correct set but not chosen) — difference
correct - student. - Print the letters they wrongly chose (chosen but not correct) —
student - correct. - Calculate a score:
len(right) - len(wrong), never below 0. Print it. - Print
PERFECTif the student answered exactly correctly — use==between the two sets, or(student ^ correct) == set().
Stretch goal. Wrap the whole logic in a function mark(correct, student) that returns a tuple (right_set, missed_set, wrong_set, score). Test it on a perfect set.
Show one possible solution
# marker.py — score a multiple-pick answer with set algebra correct = {"a", "c", "e"} student = {"a", "b", "e"} right = correct & student missed = correct - student wrong = student - correct print("Right :", right) print("Missed:", missed) print("Wrong :", wrong) score = len(right) - len(wrong) if score < 0: score = 0 print("Score :", score) if student == correct: print("PERFECT") # Stretch — wrap it up def mark(correct, student): r = correct & student m = correct - student w = student - correct s = max(0, len(r) - len(w)) return r, m, w, s print() print(mark({"a", "c", "e"}, {"a", "c", "e"})) # → ({'a', 'c', 'e'}, set(), set(), 3)
Non-negotiables: one &, two - calls, the == equality check for "perfect", and a score that uses len(). max(0, ...) is a handy way to clamp a negative score.
Recap
3 minFour operators, four English sentences. | "in either" — union. & "in both" — intersection. - "in mine, not theirs" — difference. ^ "in exactly one" — symmetric difference. Each replaces a small loop with a single symbol. Combine them and you can answer almost any "who's in which group?" question in one line.
Vocabulary Card
- union (|)
- The combined set — every item from either side, no duplicates.
- intersection (&)
- The overlap — items in both sets.
- difference (-)
- In the first set but not the second. Order matters.
- symmetric difference (^)
- In exactly one of the sets — never both.
- subset (<=) / superset (>=)
- "Is every item of this also in that?" (subset) and the reverse (superset).
Homework
4 minSave a new file compare_two_classes.py. Two Form-1 classes voted for their favourite sport.
one_alpha = {"football", "badminton", "futsal", "chess", "esports", "hockey"} one_beta = {"chess", "tennis", "esports", "swimming", "badminton", "futsal"}
Your file must:
- Print the total number of different sports mentioned across both classes (union, then
len()). - Print the sports that both classes named (intersection).
- Print the sports only 1-Alpha picked (difference).
- Print the sports only 1-Beta picked (difference, the other way).
- Print the sports voted for by exactly one class (symmetric difference).
- Use
<=to ask "is the set{"chess", "esports"}a subset of the things 1-Alpha voted for?" Print the boolean answer.
Stretch. Add a third class one_gamma and print the sports voted for by all three classes — chain intersections, like one_alpha & one_beta & one_gamma.
Sample · compare_two_classes.py
# compare_two_classes.py — set algebra on class votes one_alpha = {"football", "badminton", "futsal", "chess", "esports", "hockey"} one_beta = {"chess", "tennis", "esports", "swimming", "badminton", "futsal"} print("Distinct sports :", len(one_alpha | one_beta)) print("Both classes :", one_alpha & one_beta) print("Alpha only :", one_alpha - one_beta) print("Beta only :", one_beta - one_alpha) print("Exactly one :", one_alpha ^ one_beta) print("Subset check :", {"chess", "esports"} <= one_alpha) # Stretch — all three classes one_gamma = {"chess", "futsal", "esports", "skating", "badminton"} print("All three picked:", one_alpha & one_beta & one_gamma)
Non-negotiables: one |, one &, two - (in opposite directions), one ^ and one <= check. That's all four operators plus subset, all on one page.