Programmer's Picnic · Python Foundations · 0 → ∞
Python Sets: From 0 to Infinity
Remove duplicates and solve membership and comparison problems with set algebra.
How to learn
Read one level, type the code into the editor, predict the output, then run it. Change one line and observe the result before proceeding. All code examples work with standard Python 3 (the dictionary union example requires 3.9 or newer).
The course moves from first principles to realistic code, common mistakes, performance and a mini-project.
0 · A set stores unique values
A set is a mutable, unordered collection of distinct hashable elements. Display order is not guaranteed.
numbers = {2, 3, 2, 5}
print(len(numbers))
print(3 in numbers)
print(type(numbers).__name__)3
True
setRemember: Do not assume the order printed by a set; use sorted() for a predictable display.
1 · Creating an empty set
{} makes an empty dictionary, not a set. Write set(). Convert an iterable to a set to discard duplicates.
empty = set()
unique = set([4, 4, 2, 1])
print(type(empty).__name__)
print(sorted(unique))set
[1, 2, 4]Remember: Converting to a set does not retain original order. dict.fromkeys(items) can deduplicate while preserving order.
2 · Adding and removing
add() inserts one value; update() inserts from an iterable; discard() is safe for absent members, whereas remove() raises KeyError.
skills = {'Python'}
skills.add('SQL')
skills.update(['HTML', 'CSS'])
skills.discard('Java')
print(sorted(skills))['CSS', 'HTML', 'Python', 'SQL']Remember: pop() removes an arbitrary element; do not use it to retrieve a supposed first member.
3 · Union and intersection
Union collects all distinct members. Intersection keeps only members shared by both sets. Operators | and & provide concise syntax.
a = {'Python', 'SQL'}
b = {'SQL', 'Java'}
print(sorted(a | b))
print(sorted(a & b))['Java', 'Python', 'SQL']
['SQL']Remember: a.union(b) and a.intersection(b) have the same meanings as | and &.
4 · Difference and symmetric difference
Difference a-b keeps members only in a. Symmetric difference a^b keeps members in exactly one of the sets.
a = {1, 2, 3}
b = {3, 4}
print(sorted(a - b))
print(sorted(b - a))
print(sorted(a ^ b))[1, 2]
[4]
[1, 2, 4]Remember: Difference is directional: a-b is generally not the same as b-a.
5 · Subsets and disjoint sets
A <= B checks whether A is a subset of B. isdisjoint() checks whether two sets share no elements.
required = {'HTML', 'CSS'}
student = {'HTML', 'CSS', 'Python'}
print(required <= student)
print(required < student)
print(required.isdisjoint({'SQL'}))True
True
TrueRemember: < tests a proper subset; <= allows equality.
6 · Set comprehensions
Like list comprehensions, set comprehensions transform and filter values but produce unique results.
words = ['cat', 'dog', 'cat', 'owl']
lengths = {len(word) for word in words}
initials = {word[0] for word in words}
print(sorted(lengths))
print(sorted(initials))[3]
['c', 'd', 'o']Remember: Use generator expressions if you do not need to store the complete set.
7 · Hashability and nested data
Set members must be hashable: numbers, strings and tuples of hashable members work; lists and dictionaries do not.
coordinates = {(2, 3), (4, 5), (2, 3)}
print(len(coordinates))
print((4, 5) in coordinates)2
TrueRemember: A tuple containing an unhashable list is also unhashable.
8 · frozenset for immutable sets
frozenset cannot be modified after creation and can be used as a dictionary key if its elements are hashable.
pair = frozenset({'Asha', 'Meera'})
team_scores = {pair: 10}
print(team_scores[frozenset({'Meera', 'Asha'})])10Remember: A frozenset has no add() or remove() methods.
9 · Efficiency and order pitfalls
Average-case membership tests are O(1), although pathological hashing can degrade performance. A set has no meaningful position, so never index or slice it.
seen = set()
for code in ['A', 'B', 'A', 'C']:
if code not in seen:
seen.add(code)
print('New:', code)New: A
New: B
New: CRemember: The example prints in input order because we iterate a list, not because sets are ordered.
10 · Mini-project: club comparison
Find students who belong to both clubs, just one club, or all clubs combined.
coding = {'Asha', 'Ravi', 'Meera'}
robotics = {'Meera', 'Kabir'}
print('Both:', sorted(coding & robotics))
print('Only coding:', sorted(coding - robotics))
print('Either:', sorted(coding | robotics))Both: ['Meera']
Only coding: ['Asha', 'Ravi']
Either: ['Asha', 'Kabir', 'Meera', 'Ravi']Remember: Extension: show students in exactly one of the clubs with coding ^ robotics.
Test your understanding
Predict or explain the answer before opening the solution. Try rewriting one of the examples without copying it.
1. What is the result of type({}).__name__?
Answer: dict
Use set() for an empty set.
2. Which operation finds common elements?
Answer: a & b or a.intersection(b)
Intersection is the overlap.
3. Can you use my_set[0]?
Answer: No; sets have no positional indexing.
Sort when you need a predictable sequence.
Take it further: expand the mini-project with an input() prompt, a reusable function, input validation and three tests (normal, empty and boundary cases).
When to use each Python collection
| Type | Ordered? | Mutable? | Duplicates? | Best for |
|---|---|---|---|---|
| str | Yes | No | Yes | Text |
| list | Yes | Yes | Yes | Changing sequences |
| tuple | Yes | No* | Yes | Fixed records |
| set | No guaranteed order | Yes | No | Unique membership |
| dict | Insertion order | Yes | Keys unique | Named lookups |
* A tuple itself cannot be reassigned, but a mutable item stored inside it can still change.
Programmer's Picnic · Developed and maintained by Champak Roy · Practice with real Python, one step at a time.