Frozensets

When working with collections in Python, you’ve likely encountered set — a built-in data type that stores unique elements and supports operations like union, intersection, and difference. But Python doesn’t stop there. Today, we’re diving into the world of frozensets, the immutable sibling of sets. Understanding frozensets is essential for cases when you need a hashable, fixed collection of unique elements.

By the end of this lesson, you'll know what frozensets are, why they exist, how to create and manipulate them, and the subtle differences between sets and frozensets.

What is a Frozenset?

A frozenset is an immutable version of a Python set. Like sets, it stores unordered unique elements, but once created, you cannot add or remove items from it. This immutability makes frozensets hashable, allowing them to be used as keys in dictionaries or stored inside other sets — something regular sets cannot do.

💡 Why immutability matters

Immutability means the object cannot change after creation. This property is crucial for objects used as dictionary keys or inside other sets, because their hash values must remain constant during their lifetime.

Creating Frozensets

Creating a frozenset is straightforward. You can use the frozenset() constructor, which accepts any iterable, such as lists, tuples, or even other sets.

📌 Deep Dive: Creating Frozensets

PYTHON
# From a list
my_list = [1, 2, 3, 2]
fset1 = frozenset(my_list)
print(fset1)  # Output: frozenset({1, 2, 3})

# From a tuple
my_tuple = ('a', 'b', 'c', 'a')
fset2 = frozenset(my_tuple)
print(fset2)  # Output: frozenset({'a', 'b', 'c'})

# Directly from a set
regular_set = {4, 5, 6}
fset3 = frozenset(regular_set)
print(fset3)  # Output: frozenset({4, 5, 6})
Output
frozenset({1, 2, 3})
frozenset({'a', 'b', 'c'})
frozenset({4, 5, 6})

Notice how duplicates in the original iterable are automatically removed, just like with regular sets.

Characteristics of Frozensets

Let’s summarize the key traits of frozensets and how they compare to regular sets.

Set vs Frozenset
FeatureSetFrozenset
MutabilityMutable (can add/remove elements)Immutable (cannot change after creation)
HashableNoYes
Can be dictionary keyNoYes
Supports set operationsYesYes
SyntaxCurly braces: {...} or set()frozenset() constructor only

Using Frozensets in Practice

Since frozensets are immutable and hashable, they shine in situations where you need a constant set of unique elements that can be used as keys or stored inside other collections that require hashable elements.

For example, imagine you want to create a dictionary that maps groups of items to some values. The groups themselves are sets of items, but since sets are unhashable, you can’t use them as keys — unless you convert them to frozensets.

📌 Deep Dive: Frozensets as Dictionary Keys

PYTHON
# Using frozensets as dictionary keys
group_scores = {}

group1 = frozenset(['apple', 'banana'])
group2 = frozenset(['banana', 'cherry'])
group3 = frozenset(['apple', 'banana'])  # Same as group1

group_scores[group1] = 10
group_scores[group2] = 15

print(group_scores[group3])  # Output: 10, because group3 == group1
Output
10

Here, group1 and group3 are frozensets with the same elements, so they are considered equal keys in the dictionary.

Common Set Operations with Frozensets

Although frozensets are immutable, they support all the common set operations that do not modify the set in place. Instead, these operations return new frozenset objects.

  • union(): Combine elements from both sets
  • intersection(): Elements common to both sets
  • difference(): Elements in one set but not the other
  • symmetric_difference(): Elements in either set but not both

📌 Deep Dive: Set Operations with Frozensets

PYTHON
fset_a = frozenset([1, 2, 3])
fset_b = frozenset([3, 4, 5])

print(fset_a.union(fset_b))            # frozenset({1, 2, 3, 4, 5})
print(fset_a.intersection(fset_b))     # frozenset({3})
print(fset_a.difference(fset_b))       # frozenset({1, 2})
print(fset_a.symmetric_difference(fset_b))  # frozenset({1, 2, 4, 5})
Output
frozenset({1, 2, 3, 4, 5})
frozenset({3})
frozenset({1, 2})
frozenset({1, 2, 4, 5})

Notice these methods return new frozensets and never modify the original ones.

What You Cannot Do with Frozensets

Because frozensets are immutable, many methods available to regular sets are not supported or behave differently:

  • No add(), remove(), or discard() methods.
  • You cannot clear a frozenset.
  • No methods that mutate the set directly like update() or difference_update().

⚠️ Attempting to modify a frozenset

Trying to add or remove elements from a frozenset will raise an AttributeError. Always remember frozensets are immutable by design.

📌 Deep Dive: Mutating a Frozenset Raises Error

PYTHON
fset = frozenset([1, 2, 3])
fset.add(4)  # Raises AttributeError: 'frozenset' object has no attribute 'add'

When to Use Frozensets

Use frozensets when:

  • You need an unordered collection of unique elements that does not change.
  • You want to use a set as a key in a dictionary or as an element in another set (hashability required).
  • Your program’s logic requires immutability for safety or clarity.

In contrast, if you need to modify the collection by adding or removing elements, stick with regular sets.

Performance Considerations

Because frozensets are immutable, Python can optimize their storage and hashing. This makes lookups and membership tests (in) very efficient. However, creating a frozenset has a small upfront cost, especially for large iterables.

Once created, frozensets can be reused safely without worrying about accidental changes — ideal for use in caching, memoization, or as constant configuration sets.

Architecture of Frozensets
Architecture of Frozensets

Summary

Let’s recap the essential points:

  • Frozenset is an immutable, hashable set variant in Python.
  • Created using the frozenset() constructor from any iterable.
  • Supports all common set operations but does not allow modification.
  • Can be used as dictionary keys or elements inside other sets.
  • Trying to modify a frozenset raises AttributeError.

Understanding frozensets expands your Python toolkit, especially in situations where immutability and hashability are required.