🎯 Sets¶
Sets are unordered collections of unique elements — perfect for removing duplicates and mathematical set operations.
What is a Set?¶
Think of a set like a bag of unique marbles: you can add items, but duplicates are automatically ignored.
Creating Sets¶
# Empty set (NOT {} - that's an empty dict!)
empty = set()
# With initial values
fruits = {"apple", "banana", "cherry"}
numbers = {1, 2, 3, 4, 5}
# From other iterables
letters = set("hello") # {'h', 'e', 'l', 'o'} - duplicates removed!
from_list = set([1, 2, 2, 3]) # {1, 2, 3}
# Set comprehension
squares = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
⚠️ Important:
{}creates an empty dictionary, not a set. Useset()for empty sets.
Set Operations¶
Mathematical Set Operations¶
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# Union (all elements from both)
a | b # {1, 2, 3, 4, 5, 6}
a.union(b) # {1, 2, 3, 4, 5, 6}
# Intersection (common elements)
a & b # {3, 4}
a.intersection(b)
# Difference (in a but not b)
a - b # {1, 2}
a.difference(b)
# Symmetric difference (in one but not both)
a ^ b # {1, 2, 5, 6}
a.symmetric_difference(b)
Visual Representation¶
Set A: {1, 2, 3, 4}
Set B: {3, 4, 5, 6}
Union (A | B): {1, 2, 3, 4, 5, 6} ← Everything
Intersection (A & B): {3, 4} ← Only overlap
Difference (A - B): {1, 2} ← Only in A
Symmetric (A ^ B): {1, 2, 5, 6} ← Not in overlap
Modifying Sets¶
s = {1, 2, 3}
# Add single element
s.add(4) # {1, 2, 3, 4}
# Add multiple elements
s.update([5, 6]) # {1, 2, 3, 4, 5, 6}
# Remove (raises error if not found)
s.remove(6) # {1, 2, 3, 4, 5}
s.remove(99) # ❌ KeyError!
# Discard (no error if not found)
s.discard(99) # No error
# Pop (remove and return arbitrary element)
item = s.pop()
# Clear all
s.clear() # set()
Checking Membership¶
fruits = {"apple", "banana", "cherry"}
# Check if element exists (very fast!)
"apple" in fruits # True
"grape" in fruits # False
"grape" not in fruits # True
# Subset/Superset checks
a = {1, 2}
b = {1, 2, 3, 4}
a.issubset(b) # True (a ⊆ b)
b.issuperset(a) # True (b ⊇ a)
a < b # True (proper subset)
# Disjoint (no common elements)
{1, 2}.isdisjoint({3, 4}) # True
{1, 2}.isdisjoint({2, 3}) # False
Common Use Cases¶
Remove Duplicates (Keep Order)¶
items = [1, 3, 2, 3, 1, 4, 2]
# Using set (loses order)
unique_unordered = list(set(items)) # [1, 2, 3, 4] (order may vary)
# Keep original order (Python 3.7+)
unique_ordered = list(dict.fromkeys(items)) # [1, 3, 2, 4]
Find Common Elements¶
Check for Duplicates¶
Filter List by Allowed Values¶
allowed = {"admin", "user", "guest"}
roles = ["admin", "hacker", "user", "root"]
valid = [r for r in roles if r in allowed] # ["admin", "user"]
Frozen Sets (Immutable Sets)¶
# Regular sets are mutable
s = {1, 2, 3}
s.add(4) # Works
# Frozen sets are immutable
fs = frozenset([1, 2, 3])
fs.add(4) # ❌ AttributeError
# Useful as dictionary keys or set elements
nested = {frozenset([1, 2]), frozenset([3, 4])}
Performance¶
Sets use hash tables for O(1) average operations:
| Operation | Time Complexity |
|---|---|
| Add | O(1) |
| Remove | O(1) |
| Check membership | O(1) |
| Union/Intersection | O(min(len(a), len(b))) |
This makes in checks much faster than lists:
# For large collections:
my_list = list(range(10000))
my_set = set(range(10000))
9999 in my_list # Slow: O(n)
9999 in my_set # Fast: O(1)
Common Mistakes¶
1. Empty set syntax¶
2. Sets are unordered¶
3. Mutable elements not allowed¶
s = {[1, 2], [3, 4]} # ❌ TypeError: list is unhashable
# Use tuples instead
s = {(1, 2), (3, 4)} # ✅ Works
Quick Reference¶
# Create
s = set()
s = {1, 2, 3}
s = set([1, 2, 3])
# Add/Remove
s.add(item)
s.update([items])
s.remove(item) # Error if missing
s.discard(item) # No error
# Operations
a | b # Union
a & b # Intersection
a - b # Difference
a ^ b # Symmetric difference
# Checks
item in s
a.issubset(b)
a.issuperset(b)
a.isdisjoint(b)
Next Steps¶
Practice with examples.py, then try exercises.py!