05-03: Sets¶
A set is an unordered collection of unique, hashable elements. Duplicates are automatically removed.
Creating Sets¶
# With curly braces
s = {1, 2, 3, 4, 5}
# With set() constructor
s2 = set() # empty set
s3 = set([1, 2, 2, 3, 3, 3]) # from list — removes duplicates
print(s3) # {1, 2, 3}
# From string — unique characters
s4 = set("hello")
print(s4) # {'h', 'e', 'l', 'o'} (only unique chars)
# Duplicates are removed automatically
s5 = {1, 2, 2, 3, 3, 3, 4}
print(s5) # {1, 2, 3, 4}
# IMPORTANT: {} creates empty DICT not empty set!
empty_dict = {} # dict
empty_set = set() # set
print(type(empty_dict)) # <class 'dict'>
print(type(empty_set)) # <class 'set'>
Key Properties¶
- Unordered — no guaranteed order when printed
- Unique — no duplicate elements
- Mutable — can add/remove elements
- Unhashable items not allowed — can't contain lists or other sets
# Sets cannot contain unhashable types
valid = {1, 2.5, "hello", (1, 2), True} # OK
invalid = {[1, 2]} # TypeError: unhashable type: 'list'
Membership Testing¶
Sets excel at fast membership testing (O(1) vs O(n) for lists):
allowed = {"admin", "editor", "viewer"}
user_role = "editor"
if user_role in allowed:
print("Access granted")
print("admin" in allowed) # True
print("guest" in allowed) # False
print("guest" not in allowed) # True
Adding Elements¶
s = {1, 2, 3}
# add() — add one element (no-op if already present)
s.add(4)
print(s) # {1, 2, 3, 4}
s.add(2) # no-op — 2 already in set
print(s) # {1, 2, 3, 4}
# update() — add multiple elements from any iterable
s.update([5, 6, 7])
print(s) # {1, 2, 3, 4, 5, 6, 7}
s.update("abc") # adds 'a', 'b', 'c'
s.update({10, 11}, [12, 13]) # multiple iterables
Removing Elements¶
s = {1, 2, 3, 4, 5}
# remove() — raises KeyError if not found
s.remove(3)
print(s) # {1, 2, 4, 5}
s.remove(9) # KeyError!
# discard() — no error if not found (safer)
s.discard(2)
print(s) # {1, 4, 5}
s.discard(99) # no error
# pop() — removes and returns an arbitrary element
item = s.pop()
print(item) # some element (order unpredictable)
# clear() — remove all elements
s.clear()
print(s) # set()
Set Operations¶
Union — all unique elements from both sets¶
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6} — operator
print(a.union(b)) # {1, 2, 3, 4, 5, 6} — method
print(a.union(b, {7, 8})) # {1, 2, 3, 4, 5, 6, 7, 8} — multiple sets
Intersection — elements in both sets¶
Difference — elements in a but not b¶
Symmetric Difference — elements in either but not both¶
Subset and Superset¶
x = {1, 2}
y = {1, 2, 3, 4}
print(x.issubset(y)) # True — all of x is in y
print(x <= y) # True — subset operator
print(x < y) # True — proper subset (x != y)
print(y.issuperset(x)) # True — y contains all of x
print(y >= x) # True
print(y > x) # True — proper superset
print(x.isdisjoint({3, 4})) # True — no common elements
print(x.isdisjoint({2, 3})) # False — 2 is common
In-Place Set Operations¶
a = {1, 2, 3}
b = {3, 4, 5}
a |= b # a = a | b (union)
print(a) # {1, 2, 3, 4, 5}
a &= {2, 3, 4} # a = a & {2,3,4} (intersection)
print(a) # {2, 3, 4}
a -= {3} # a = a - {3} (difference)
print(a) # {2, 4}
a ^= {1, 2} # a = a ^ {1,2} (symmetric diff)
print(a) # {1, 4}
Set Comprehensions¶
# All unique characters (no spaces) in a sentence
text = "hello world python programming"
unique_chars = {c for c in text if c != " "}
print(sorted(unique_chars))
# Squares of even numbers
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0, 4, 16, 36, 64}
Practical Use Cases¶
Remove duplicates from a list (preserving order)¶
original = [1, 3, 2, 1, 4, 3, 5]
# Simple but loses order:
unique = list(set(original))
# Preserving order:
seen = set()
unique_ordered = []
for item in original:
if item not in seen:
unique_ordered.append(item)
seen.add(item)
print(unique_ordered) # [1, 3, 2, 4, 5]
Fast lookup¶
# Using a set for O(1) lookup
stop_words = {"the", "a", "an", "is", "are", "was", "were", "in", "on"}
text = "the quick brown fox is in the forest"
filtered = [word for word in text.split() if word not in stop_words]
print(filtered) # ['quick', 'brown', 'fox', 'forest']
Finding common/unique items¶
students_A = {"Alice", "Bob", "Charlie", "Dave"}
students_B = {"Bob", "Dave", "Eve", "Frank"}
# Students in both classes
both = students_A & students_B
print("Both:", both) # {'Bob', 'Dave'}
# Only in class A
only_A = students_A - students_B
print("Only A:", only_A) # {'Alice', 'Charlie'}
# Either class (union)
either = students_A | students_B
print("All:", either)
# Exactly one class
one_only = students_A ^ students_B
print("One only:", one_only) # {'Alice', 'Charlie', 'Eve', 'Frank'}
Iteration¶
s = {3, 1, 4, 1, 5, 9, 2, 6}
# Iterate (order not guaranteed)
for item in s:
print(item, end=" ")
# Sort for deterministic output
for item in sorted(s):
print(item, end=" ")
# 1 2 3 4 5 6 9
print(len(s)) # 7 (duplicates removed)
frozenset — Immutable Set¶
A frozenset is an immutable version of a set — hashable, so it can be used as a dictionary key or as an element of another set:
fs = frozenset([1, 2, 3, 4])
print(fs) # frozenset({1, 2, 3, 4})
# Can be used as dict key
config = {frozenset(["read", "write"]): "admin"}
# Can be element of set
s = {frozenset({1, 2}), frozenset({3, 4})}
Complete Method Reference¶
| Method | Operator | Description |
|---|---|---|
add(x) |
— | Add element |
discard(x) |
— | Remove if present (no error) |
remove(x) |
— | Remove (KeyError if absent) |
pop() |
— | Remove & return arbitrary element |
clear() |
— | Remove all elements |
union(s) |
\| |
All elements from both |
intersection(s) |
& |
Common elements |
difference(s) |
- |
In self, not in s |
symmetric_difference(s) |
^ |
In one or the other, not both |
issubset(s) |
<= |
All of self in s |
issuperset(s) |
>= |
All of s in self |
isdisjoint(s) |
— | No common elements |
update(s) |
\|= |
Add all from s |
intersection_update(s) |
&= |
Keep only common elements |
difference_update(s) |
-= |
Remove elements in s |
symmetric_difference_update(s) |
^= |
Keep only non-common |
Practice Problems¶
# 1. Count unique words in a sentence
sentence = "to be or not to be that is the question"
unique_words = set(sentence.split())
print(f"Unique words: {len(unique_words)}")
# 2. Intersection of multiple sets
lists = [[1,2,3,4], [2,3,4,5], [3,4,5,6]]
common = set(lists[0])
for lst in lists[1:]:
common &= set(lst)
print(common) # {3, 4}
# 3. Check if two strings are anagrams
def are_anagrams(s1, s2):
return set(s1.lower()) == set(s2.lower()) and \
sorted(s1.lower()) == sorted(s2.lower())
print(are_anagrams("listen", "silent")) # True
print(are_anagrams("hello", "world")) # False
# 4. Power set (all subsets)
def power_set(s):
result = [set()]
for item in s:
result += [existing | {item} for existing in result]
return result
print(power_set({1, 2, 3}))
Exercises: 05-03: Exercises — Sets
⬅️ Previous: 05-02: Tuples ➡️ Next: 05-04: Dictionaries