Python > Core Python Basics > Data Structures > Frozen Sets

Introduction to Frozen Sets in Python

frozenset is an immutable version of Python's set object. While you can modify sets (add or remove elements), a frozen set remains constant after creation. This immutability makes them usable as dictionary keys or elements of other sets, which is not possible with regular sets.

Creating Frozen Sets

Frozen sets can be created from any iterable, such as lists, sets, or tuples. The frozenset() constructor takes an iterable as its argument and returns a new frozen set containing the elements of that iterable. Once created, a frozen set cannot be modified.

my_set = {1, 2, 3, 4}
my_frozen_set = frozenset(my_set)
print(my_frozen_set)

my_frozen_set_from_list = frozenset([5, 6, 7])
print(my_frozen_set_from_list)

my_frozen_set_from_tuple = frozenset((8, 9, 10))
print(my_frozen_set_from_tuple)

Basic Operations on Frozen Sets

Frozen sets support standard set operations like union, intersection, difference, and symmetric difference. Since they are immutable, these operations return new frozen sets rather than modifying the original ones. You can also check if a frozen set is a subset or superset of another frozen set.

frozen_set_1 = frozenset({1, 2, 3})
frozen_set_2 = frozenset({3, 4, 5})

# Union
union_set = frozen_set_1 | frozen_set_2  # Equivalent to frozen_set_1.union(frozen_set_2)
print(f"Union: {union_set}")

# Intersection
intersection_set = frozen_set_1 & frozen_set_2  # Equivalent to frozen_set_1.intersection(frozen_set_2)
print(f"Intersection: {intersection_set}")

# Difference
difference_set = frozen_set_1 - frozen_set_2  # Equivalent to frozen_set_1.difference(frozen_set_2)
print(f"Difference: {difference_set}")

# Symmetric Difference
symmetric_difference_set = frozen_set_1 ^ frozen_set_2  # Equivalent to frozen_set_1.symmetric_difference(frozen_set_2)
print(f"Symmetric Difference: {symmetric_difference_set}")

# Subset and Superset
set_a = frozenset({1, 2})
set_b = frozenset({1, 2, 3})
print(f"Is set_a a subset of set_b? {set_a.issubset(set_b)}")
print(f"Is set_b a superset of set_a? {set_b.issuperset(set_a)}")

When to use them

Use frozen sets when you need an immutable collection of unique elements, especially when you need to use sets as dictionary keys or elements within other sets. Their immutability provides data integrity and makes them suitable for caching or representing states in a program.

Real-Life Use Case Section

Imagine a system where you need to store configurations. Each configuration consists of a unique set of parameters. You can use a frozenset to represent the set of parameters for each configuration, making the configuration hashable and thus suitable for use as a dictionary key. This allows you to quickly retrieve configuration details based on the set of parameters.

configurations = {
    frozenset(['param1', 'param2']): {'value1': 10, 'value2': 20},
    frozenset(['param3', 'param4']): {'value3': 30, 'value4': 40}
}

# Accessing configuration based on parameter set
params = frozenset(['param1', 'param2'])
if params in configurations:
    print(f"Configuration for {params}: {configurations[params]}")

Memory footprint

Frozen sets generally have a similar memory footprint to regular sets. The major difference is that since frozensets are immutable, Python can sometimes optimize their storage in certain cases, potentially leading to slightly better memory usage, especially when many copies or variations of the set aren't required. However, the difference is often negligible.

import sys

my_set = {i for i in range(1000)}
frozen_set_test = frozenset(my_set)

set_size = sys.getsizeof(my_set)
frozen_set_size = sys.getsizeof(frozen_set_test)

print(f"Size of set: {set_size} bytes")
print(f"Size of frozenset: {frozen_set_size} bytes")

Pros

  • Immutability: Ensures that the set's contents cannot be changed after creation.
  • Hashable: Can be used as keys in dictionaries and elements in other sets.
  • Thread-safe: Because they are immutable, frozen sets are safe to use in multithreaded environments without locks.

Cons

  • Immutability: Can be a disadvantage when you need to modify the set's contents. You would need to create a new frozen set instead.
  • No in-place modification methods: Methods like add() or remove() are not available.

Best Practices

  • Use frozen sets when you require immutability.
  • Consider using sets and converting them to frozen sets when you need to perform several modifications before making them immutable.
  • When passing data around in a multithreaded environment, use frozen sets to avoid race conditions.

Interview Tip

Be prepared to discuss the difference between sets and frozen sets, and their use cases. Explain why frozen sets are hashable and how that property makes them suitable for use as dictionary keys. Demonstrate your understanding of the immutability advantages.

Alternatives

If you need a mutable set, use a standard set. If immutability is required but a set-like structure is not, consider using tuples or immutable lists. However, note that tuples and lists do not enforce uniqueness like sets do.

FAQ

  • Can I add or remove elements from a frozen set?

    No, frozen sets are immutable. You cannot add or remove elements after they are created.
  • Why would I use a frozen set over a regular set?

    Use a frozen set when you need a set that can be used as a dictionary key or as an element of another set, or when you want to guarantee that the set's contents will not be modified.
  • Are frozen sets hashable?

    Yes, frozen sets are hashable because they are immutable. This means you can use them as keys in dictionaries.