Lesson 10 · Python data types deep dive
Python Frozensets Explained: Immutable Sets in Practice | Data Types #10
Video ten of the twelve-part series: frozenset, set's immutable, hashable cousin. Construction, all eight public frozenset methods, immutability, and…
- CoursePython data types deep dive
- Lesson10 of 12
- Video14 min
- FormatJupyter notebook · 10 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbPython Data Types Deep-Dive, Video 10: Frozensets (frozenset)#
- Video ten of the twelve-part series: frozenset, set's immutable, hashable cousin.
- Construction, all eight public frozenset methods, immutability, and hashability, including using a frozenset as a dict key or a member of another set.
- Let's get into it.
Part 1: What Makes frozenset Different#
numbers = frozenset([1, 2, 3, 2, 1])
print(numbers)
print(type(numbers))
print(len(numbers))
print(hash(numbers))
regular_set = {1, 2, 3}
try:
hash(regular_set)
except TypeError as e:
print(f'Caught: {e}')
Part 2: Construction#
empty = frozenset()
print(empty)
from_list = frozenset([1, 2, 3])
from_string = frozenset('mississippi')
from_set = frozenset({4, 5, 6})
from_range = frozenset(range(5))
print(from_list, from_string, from_set, from_range)
Part 3: The Eight Methods#
a = frozenset([1, 2, 3, 4])
b = frozenset([3, 4, 5, 6])
print(a.union(b))
print(type(a.union(b)))
print(a.intersection(b))
print(a.difference(b))
print(a.symmetric_difference(b))
print(a | b)
print(a & b)
a = frozenset([1, 2, 3])
b = frozenset([1, 2, 3, 4, 5])
c = frozenset([10, 20])
print(a.issubset(b))
print(b.issuperset(a))
print(a.isdisjoint(c))
copied = a.copy()
print(copied)
print(copied is a)
Part 4: Immutability in Practice#
frozen = frozenset([1, 2, 3])
print(hasattr(frozen, 'add'))
print(hasattr(frozen, 'remove'))
print(hasattr(frozen, 'union'))
try:
frozen.add(4)
except AttributeError as e:
print(f'Caught: {e}')
Part 5: Hashability: Nested Sets and Dict Keys#
try:
nested = {1, 2, {3, 4}}
except TypeError as e:
print(f'Caught: {e}')
nested_ok = {1, 2, frozenset([3, 4])}
print(nested_ok)
group_permissions = {
frozenset(['read']): 'viewer',
frozenset(['read', 'write']): 'editor',
frozenset(['read', 'write', 'delete']): 'admin'
}
user_perms = frozenset(['write', 'read'])
print(group_permissions[user_perms])
print(group_permissions[frozenset(['read'])])
Part 6: frozenset vs set, When to Use Which#
VALID_STATUSES = frozenset(['pending', 'active', 'completed', 'cancelled'])
def check_status(status):
return status in VALID_STATUSES
print(check_status('active'))
print(check_status('unknown'))
try:
VALID_STATUSES.add('archived')
except AttributeError as e:
print(f'Caught: {e}')
Part 7: Common Patterns#
cache = {}
def expensive_lookup(*args):
key = frozenset(args)
if key in cache:
print('cache hit')
return cache[key]
print('computing...')
result = sum(args)
cache[key] = result
return result
print(expensive_lookup(1, 2, 3))
print(expensive_lookup(3, 2, 1))
edges = set()
edges.add(frozenset(['A', 'B']))
edges.add(frozenset(['B', 'A']))
edges.add(frozenset(['B', 'C']))
print(len(edges))
print(edges)
Wrap-Up: What You Learned#
- frozenset is set's immutable, hashable cousin, with no literal syntax; frozenset() is the only way to build one.
- All eight public methods are read-only: copy, union, intersection, difference, symmetric_difference, isdisjoint, issubset, issuperset.
- No add, remove, discard, pop, clear, or update at all; every mutating method is genuinely absent.
- Because it's hashable, frozenset can nest inside another set or serve as a dict key, unlike a regular set.
- When to reach for frozenset over set, memoization cache keys, and unordered graph edges.
- That's all eight public frozenset methods covered. Next up: bytes, for raw immutable binary data.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



