Exercises — Sets — unique elements, set operations (union, intersection, difference)
Throughout, and are Python sets. We reuse only four symbols, all defined in the parent:
- (union, Python
|) — "in or ", - (intersection, Python
&) — "in and ", - (difference, Python
-) — "in but not ", - (symmetric difference, Python
^) — "in exactly one of them".
If any of those feels shaky, the truth-table view lives in Boolean Logic — AND, OR, XOR.
Level 1 — Recognition
Can you read a set correctly and predict its size/contents?
Recall Solution 1.1
WHAT: A set stores each value at most once — duplicate inserts are silently dropped.
WHY: each value is hashed to an address; if that address already holds an equal value, insertion is skipped (the mechanism in Hashing and Hashable Types).
Collapsing duplicates: .
There are 4 distinct values, so len(s) prints 4.
Recall Solution 1.2
a = {}→ an empty dictionary (Python breaks the{}tie in favour of dicts — see Dictionaries — key-value & why {} is a dict).b = set()→ the empty set ✅.len(b)is0.c = {0}→ a set with one element, the number0. It is not empty;len(c)is1. So onlybis an empty set.
Recall Solution 1.3
Membership x in t answers "is an element equal to x present?" — case-sensitive for strings.
"cat" in t→True(exact match present)."Cat" in t→False("Cat"≠"cat"; different hash, different bucket)."bird" not in t→True("bird"is absent, so not in is true).
Level 2 — Application
Run the four operations by hand on concrete data.

Recall Solution 2.1
Read the Venn picture above: left-only petal is , the lens in the middle is , the right-only petal is .
- Union = everything in either petal or the lens = .
- Intersection = only the shared lens = .
- Difference = left petal (in , not ) = .
- Reverse difference = right petal = . Note — order matters for .
- Symmetric difference = both petals, lens removed = .
Recall Solution 2.2
(a) set(nums) collapses to . Wrapping in list() gives those four values, but order is not guaranteed — the set is arranged by hash, not by when you inserted. So all we can promise about the contents is the set .
(b) To keep first-seen order, use dict.fromkeys (dict keys are unique and remember insertion order):
ordered = list(dict.fromkeys(nums)) # [7, 3, 1, 9]First appearances are 7, then 3, then 1, then 9 → [7, 3, 1, 9].
Recall Solution 2.3
- (a) both = intersection
post1 & post2= . - (b) only post1 = difference
post1 - post2= (the only tag inpost1missing frompost2). - (c) exactly one = symmetric difference
post1 ^ post2= (hashingonly in post1,listsonly in post2).
Level 3 — Analysis
Reason about behaviour, mutation, and cost.
Recall Solution 3.1
Key distinction: union returns a new set and leaves the caller untouched; update mutates in place and returns None.
- (i)
Ais unchanged by.union(...)→{1, 2}. - (ii)
Cis the fresh union →{1, 2, 3}. - (iii)
D.update(B)foldsBintoD→{1, 2, 3}.
Recall Solution 3.2
(a) One membership test costs for a set (single hash → one bucket) and for a list (scan all ). Doing it times: (b) Worst case each of the lookups scans all items: The set version does about hash lookups instead — a factor of fewer. That gap is why sets exist for membership work.
Recall Solution 3.3
A set element must be hashable — roughly, immutable so its hash never changes (see Hashing and Hashable Types).
- (a) OK ✅ — tuples are immutable, hence hashable.
- (b)
TypeError❌ — alistis mutable, so unhashable. - (c) OK ✅ — an int, a str, and a 1-element tuple are all hashable.
- (d)
TypeError❌ — a plainsetis itself mutable, so it can't be an element. (The immutable cousinfrozensetwould work.)
Level 4 — Synthesis
Combine operations to solve a real task; verify an identity.
Recall Solution 4.1
Left side — symmetric difference (in exactly one set): Right side — union minus the shared middle: Both give ✔. The picture: union collects everything; the intersection is the "double-counted" lens; remove it and only the two exclusive petals survive — exactly "in one set only."
Recall Solution 4.2
(a) editor beyond guest = editor - guest = .
(b) admin-only vs the union of the others:
Because editor | guest = , subtracting from admin leaves {"delete"}.
(c) "every guest action is an editor action" is the subset test guest <= editor (equivalently guest.issubset(editor)). Since guest = {"read"} and "read" ∈ editor, this is True.
Level 5 — Mastery
Design and prove — no hand-holding.
Recall Solution 5.1
WHAT: flatten every value into one set, then take its length.
WHY a set: it dedups automatically and joins effortlessly via union. Using set().union(*map(set, data)) unions all sublists at once:
distinct = set().union(*map(set, data))
print(len(distinct))Values seen: → distinct set → count 4.
(Equivalently len({x for row in data for x in row}) — a set comprehension.)
Recall Solution 5.2
(a) Take , : So is not symmetric. (b) The symmetric difference is order-independent because it unions both differences: Same result → ✔. Union is commutative, so wrapping the two (non-symmetric) differences in a union restores symmetry.
Recall Solution 5.3
Design idea: keep a seen set. Walk left to right; if the current item is already in seen, it's the first repeat — return it. Membership is , so total is .
def first_dup(seq):
seen = set()
for x in seq:
if x in seen: # O(1) check
return x
seen.add(x)
return NoneTrace on [3, 1, 4, 1, 5, 3]:
| step | x | seen before check | in seen? | action |
|---|---|---|---|---|
| 1 | 3 | {} | no | add 3 |
| 2 | 1 | {3} | no | add 1 |
| 3 | 4 | {1,3} | no | add 4 |
| 4 | 1 | {1,3,4} | yes | return 1 |
Answer: 1 (the second 1 is the first value seen twice).
Recall Self-test checklist
- I can predict
lenafter duplicates collapse.Level 1 ::: yes - I compute all four ops from a Venn picture.
Level 2 ::: yes - I explain
unionvsupdateand the vs gap.Level 3 ::: yes - I verify and model permissions.
Level 4 ::: yes - I design an duplicate detector and prove non-commutativity.
Level 5 ::: yes
Connections
- Parent topic
- Boolean Logic — AND, OR, XOR — the AND/OR/XOR behind
- Big-O Notation & Time Complexity — why the set version wins
- Hashing and Hashable Types — why membership works
- Tuples — immutable sequences — valid hashable set elements
- Lists — ordered, indexed collections — order vs speed trade-off
- Dictionaries — key-value & why {} is a dict —
{}is a dict,dict.fromkeyskeeps order