Frozen Set

Learn about frozen sets in Python.

Ali Berro

By Ali Berro

8 min read Section
From: Python Fundamentals: From Zero to Hero

Frozen Set

A frozen set is an immutable version of a set. Frozen sets cannot be changed after creation which means that elements cannot be added, removed, or modified. Since they are immutable, frozen sets are hashable and can be used as dictionary keys or as elements in other sets.

Key Properties of Frozen Sets

  • Immutable: Cannot be modified after creation
  • Hashable: Can be used as dictionary keys and set elements
  • Unordered: Elements have no defined order (like regular sets)
  • Unique elements: No duplicates allowed
  • Unindexed: Elements cannot be accessed by index

Creating a Frozen Set

Frozen sets are created using the frozenset() constructor, which takes an iterable:

# From a list
fs = frozenset([1, 2, 3])
print(fs) # frozenset({1, 2, 3})
# From a string
chars = frozenset("hello") # frozenset({'h', 'e', 'l', 'o'})
# From a range
numbers = frozenset(range(5)) # frozenset({0, 1, 2, 3, 4})
# Empty frozen set
empty = frozenset()
print(empty) # frozenset()

Note

Like regular sets, frozen sets automatically remove duplicates and are unordered. The order of elements when printing may vary.

Immutability and Hashability

The key advantage of frozen sets is their immutability, which makes them hashable:

fs = frozenset([1, 2, 3])
# Frozen sets are hashable
print(hash(fs)) # Some hash value
# Can be used as dictionary keys
d = {fs: "value"}
print(d[fs]) # value
# Can be used as set elements
set_of_frozen_sets = {frozenset([1, 2]), frozenset([3, 4])}
print(set_of_frozen_sets) # {frozenset({1, 2}), frozenset({3, 4})}

Tip

Regular sets cannot be used as dictionary keys or set elements because they are mutable and therefore unhashable. Frozen sets solve this limitation.

Checking Membership

Elements can be checked for existence in a frozen set using the in and not in operators:

fs = frozenset([1, 2, 3, 4, 5])
print(3 in fs) # True
print(10 in fs) # False
print(2 not in fs) # False

Looping Over a Frozen Set

Frozen sets can be iterated over using a for loop:

fs = frozenset([1, 2, 3, 4, 5])
for element in fs:
print(element)

Frozen Set Operations

Frozen sets support all set operations that return new sets (since they cannot be modified in place):

  • union(iterable1, iterable2, ...): Returns a new frozen set containing all elements from the frozen set and all given iterables XSTX \cup S \cup T \cup \ldots.
  • intersection(iterable1, iterable2, ...): Returns a new frozen set containing only elements that are common to the frozen set and all given iterables XSTX \cap S \cap T \cap \ldots.
  • difference(iterable1, iterable2, ...): Returns a new frozen set containing elements that are in the frozen set but not in any of the given iterables XST...X - S - T - ....
  • symmetric_difference(iterable): Returns a new frozen set containing elements that are in either the frozen set or the iterable, but not in both XSX \triangle S.
  • issubset(iterable): Returns True if all elements of the frozen set are in the given iterable.
  • issuperset(iterable): Returns True if all elements of the given iterable are in the frozen set.
  • isdisjoint(iterable): Returns True if the frozen set and the given iterable have no elements in common (their intersection is empty).
union
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([3, 4, 5])
result = fs1.union(fs2)
print(result) # frozenset({1, 2, 3, 4, 5})
# Can also use the | operator
result = fs1 | fs2 # frozenset({1, 2, 3, 4, 5})
intersection
fs1 = frozenset([1, 2, 3, 4])
fs2 = frozenset([3, 4, 5, 6])
result = fs1.intersection(fs2)
print(result) # frozenset({3, 4})
# Can also use the & operator
result = fs1 & fs2 # frozenset({3, 4})
difference
fs1 = frozenset([1, 2, 3, 4, 5])
fs2 = frozenset([3, 4])
result = fs1.difference(fs2)
print(result) # frozenset({1, 2, 5})
# Can also use the - operator
result = fs1 - fs2 # frozenset({1, 2, 5})
symmetric_difference
fs1 = frozenset([1, 2, 3, 4])
fs2 = frozenset([3, 4, 5, 6])
result = fs1.symmetric_difference(fs2)
print(result) # frozenset({1, 2, 5, 6})
# Can also use the ^ operator
result = fs1 ^ fs2 # frozenset({1, 2, 5, 6})
issubset
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([1, 2, 3, 4, 5])
print(fs1.issubset(fs2)) # True
# Can also use the <= operator
print(fs1 <= fs2) # True
issuperset
fs1 = frozenset([1, 2, 3, 4, 5])
fs2 = frozenset([1, 2, 3])
print(fs1.issuperset(fs2)) # True
# Can also use the >= operator
print(fs1 >= fs2) # True
isdisjoint
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([4, 5, 6])
print(fs1.isdisjoint(fs2)) # True
fs3 = frozenset([3, 4, 5])
print(fs1.isdisjoint(fs3)) # False (they share element 3)

Why Use Frozen Sets?

1. Dictionary Keys

Frozen sets can be used as dictionary keys, which is useful for representing relationships or mappings:

# Representing edges in a graph
edges = {
frozenset([1, 2]): "edge_1_2",
frozenset([2, 4]): "edge_2_4",
frozenset([1, 3]): "edge_1_3"
}
print(edges[frozenset([1, 2])]) # edge_1_2

2. Sets of Sets

Frozen sets can be elements in other sets, allowing for sets of sets:

# Graph representation: set of edges (each edge is a frozen set)
graph = {
frozenset([1, 2]),
frozenset([2, 4]),
frozenset([1, 3])
}
print(graph) # {frozenset({1, 2}), frozenset({2, 4}), frozenset({1, 3})}

Exercises

Exercise 1: Create a frozen set from a list

Write a program that reads the size of a list, then reads the elements, creates a frozen set from the list, and prints it.

Create Frozen Set

Checks: 0 times
Answer:
n = int(input())
elements = []
for i in range(n):
elements.append(input())
fs = frozenset(elements)
print(fs)

Exercise 2: Use frozen set as dictionary key

Write a program that creates a dictionary where keys are frozen sets representing pairs of numbers, and values are strings describing the pair. Create entries for pairs (1,2), (2,3), and (1,3), then print the dictionary.

Frozen Set as Dictionary Key

Checks: 0 times
Answer:
d = {
frozenset([1, 2]): "pair_1_2",
frozenset([2, 3]): "pair_2_3",
frozenset([1, 3]): "pair_1_3"
}
print(d)

Exercise 3: Set of frozen sets (graph edges)

Write a program that creates a set of frozen sets to represent graph edges. Create edges (1,2), (2,3), (3,4), and (1,4), then print the set.

Set of Frozen Sets

Checks: 0 times
Answer:
graph = {
frozenset([1, 2]),
frozenset([2, 3]),
frozenset([3, 4]),
frozenset([1, 4])
}
print(graph)

Exercise 4: Dictionary with frozen set keys

Write a program that reads the number of entries n, then for each entry reads two numbers representing a pair, creates a frozen set from the pair, and uses it as a key in a dictionary with value "edge_{first}_{second}". Print the dictionary.

Dictionary with Frozen Set Keys

Checks: 0 times
Answer:
n = int(input())
d = {}
for i in range(n):
first = int(input())
second = int(input())
key = frozenset([first, second])
d[key] = f"edge_{first}_{second}"
print(d)

Exercise 5: Count unique pairs using frozen sets

Write a program that reads the number of pairs n, then for each pair reads two numbers, creates a frozen set for each pair, adds them to a set, and prints the count of unique pairs (where order doesn’t matter, so (1,2) and (2,1) are the same).

Count Unique Pairs

Checks: 0 times
Answer:
n = int(input())
unique_pairs = set()
for i in range(n):
first = int(input())
second = int(input())
pair = frozenset([first, second])
unique_pairs.add(pair)
print(len(unique_pairs))

Exercise 6: Graph representation with frozen sets

Write a program that reads the number of edges n, then for each edge reads two vertices, creates a graph as a set of frozen sets (each edge is a frozen set), and prints the graph. Then check if edge (1,2) exists in the graph and print "Yes" or "No".

Graph Representation

Checks: 0 times
Answer:
n = int(input())
graph = set()
for i in range(n):
v1 = int(input())
v2 = int(input())
edge = frozenset([v1, v2])
graph.add(edge)
print(graph)
edge_to_check = frozenset([1, 2])
if edge_to_check in graph:
print("Yes")
else:
print("No")

Course Progress

Section 27 of 61

Back to Course