Mathew K Analytics

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…

⬇ Download notebookOpen in Colab ↗

What you'll learn

Data

No separate download needed — the notebook creates or downloads everything it uses.

📓 Full notebook

Download .ipynb

Python 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}')
frozenset({1, 2, 3})
<class 'frozenset'>
3
-272375401224217160
Caught: unhashable type: 'set'

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)
frozenset()
frozenset({1, 2, 3}) frozenset({'m', 'i', 'p', 's'}) frozenset({4, 5, 6}) frozenset({0, 1, 2, 3, 4})

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)
frozenset({1, 2, 3, 4, 5, 6})
<class 'frozenset'>
frozenset({3, 4})
frozenset({1, 2})
frozenset({1, 2, 5, 6})
frozenset({1, 2, 3, 4, 5, 6})
frozenset({3, 4})
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)
True
True
True
frozenset({1, 2, 3})
True

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}')
False
False
True
Caught: 'frozenset' object has no attribute 'add'

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)
Caught: unhashable type: 'set'
{frozenset({3, 4}), 1, 2}
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'])])
editor
viewer

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}')
True
False
Caught: 'frozenset' object has no attribute 'add'

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))
computing...
6
cache hit
6
edges = set()
edges.add(frozenset(['A', 'B']))
edges.add(frozenset(['B', 'A']))
edges.add(frozenset(['B', 'C']))
print(len(edges))
print(edges)
2
{frozenset({'B', 'A'}), frozenset({'C', 'B'})}

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.