frozenset()

The immutable sibling of set — same operations minus mutation, plus hashability.

Built-in function / typePython 2.4+Live demo
Common call
CONSTANTS = frozenset({"a", "b", "c"})
Returns
a frozenset object — read-only, hashable
Replaces
a regular set when you need to use the set as a dict key, cache key, or set element
Watch out
no add/discard/clear — attempts raise AttributeError; frozenset.copy() may return self
frozenset([iterable])
frozenset

Demo

Live evaluation
Try:
Inputs
itemslistcomma-separated items
Output
frozenset({'a', 'b', 'c'})
'frozenset({\'[object Object]\'})'

frozenset takes an iterable and stores its UNIQUE elements — duplicates collapse, exactly like set. The result is IMMUTABLE: no add, no discard, no clear. Because it is immutable, it is hashable — you can use a frozenset as a dict key or put it inside another set. That is the primary reason to prefer it over set. The display order is not meaningful (set element order is arbitrary).

Parameters

NameTypeRequiredDescription
iterableiterableno (())Any iterable — the frozenset takes the unique elements. Empty or omitted → an empty frozenset.

Return value

frozensetAn immutable set containing the unique elements of iterable. Supports all read operations of set (union, intersection, contains, len, iteration) but none of the mutations (add, discard, clear, update). Hashable, so it can be a dict key or a member of another set.

Common patterns

Constants that should not change
Module-level or class-level immutable configuration.
ALLOWED_METHODS = frozenset({"GET", "POST", "PUT"})
Dict key that is a set
Regular sets are not hashable — frozenset is the fix.
cache = {}
cache[frozenset({"user", "admin"})] = compute(...)
Set of sets
You cannot put a set inside a set — use frozenset for the inner sets.
clusters = {frozenset({"a", "b"}), frozenset({"c", "d"})}
Set operations return a set of the SAME type
Union / intersection of frozensets is a frozenset.
frozenset({1,2}) | frozenset({2,3})   # frozenset({1,2,3})

Examples

1. Basic
frozenset([1, 2, 3])
Returns
frozenset({1, 2, 3})
2. Duplicates collapse
frozenset("mississippi")
Returns
frozenset({"m", "i", "s", "p"})
3. Empty
frozenset()
Returns
frozenset()
4. From dict keys
frozenset({"a": 1, "b": 2})
Returns
frozenset({"a", "b"})
5. Cannot add
frozenset([1]).add(2)
Returns
AttributeError: 'frozenset' object has no attribute 'add'
6. Hashable
hash(frozenset([1, 2, 3]))
Returns
some integer # works, unlike set
7. Set operations
frozenset({1,2}) | frozenset({2,3})
Returns
frozenset({1, 2, 3})

Pitfalls

1. No mutation methods
frozenset intentionally lacks add, discard, remove, pop, clear, update, and all the *_update variants. Any attempt raises AttributeError. If you need to add or remove, build a NEW frozenset with set operations.
AttributeError
fs = frozenset([1, 2])
fs.add(3)
AttributeError: 'frozenset' object has no attribute 'add'
Build a new one
fs2 = fs | {3}
frozenset({1, 2, 3})
2. frozenset.copy() may return SELF
CPython optimizes: since frozensets are immutable, a copy is indistinguishable from the original for correctness. `fs.copy() is fs` is True. Behavior of the value is identical either way.
Same object
fs = frozenset({1, 2})
fs.copy() is fs
True # optimization
Test equality
fs.copy() == fs
True
3. Elements must still be hashable
A frozenset itself is hashable — but the ELEMENTS still must be hashable (same rule as set). You cannot put a list or a dict inside a frozenset.
List inside
frozenset([[1, 2], [3, 4]])
TypeError: unhashable type: 'list'
Tuple inside
frozenset([(1, 2), (3, 4)])
frozenset({(1, 2), (3, 4)})
4. Empty frozenset displays as `frozenset()`, not `frozenset({})`
{} is a dict literal, not an empty set. Python knows this and shows an empty frozenset as `frozenset()`. Beginners sometimes expect the {} form.
Expected {}
frozenset()   # display
frozenset() # not frozenset({})
That is normal
# same reason set() displays as set(), not {}

When to use

Use it
  • A set that must be a dict key or an element of another set
  • Module-level constants that should not accidentally mutate
  • Cache keys that involve set membership
  • Data-model IDs that need value semantics but include an unordered subset
Reach for something else
  • You will add or remove elements → use set
  • Element order matters → sets (frozen or not) do not guarantee order
  • Only reading, single-use → set is fine
  • Small fixed-membership check → a tuple can be faster for small sizes

Notes

Complexity
O(n) to construct; same as set for lookup and set operations
Return
A frozenset object — immutable
CPython impl
Objects/setobject.c :: frozenset_new — shares implementation with set
Memory
Similar to set — a hash table with load factor
Thread-safe
Yes — frozensets are immutable

FAQ

set is mutable — supports add, discard, clear, update. frozenset is immutable — no mutation methods. frozenset is hashable (usable as dict key or set element); set is not. Both share all read operations and set-algebra methods.

History

2.4
frozenset added along with set as a built-in type.