π§ Python Immutable Data Structures β Tuples, frozenset, and More
π§² Introduction β Why Use Immutable Data Structures?
In Python, most built-in data types are mutable (e.g., lists, dictionaries, sets). This means their contents can be modified after creationβwhich can lead to:
- β Unexpected side effects
- π Hard-to-debug state changes
- π Unsafe concurrent behavior
Immutable data structures, on the other hand:
- β Cannot be changed after creation
- β Are hashable and usable as dictionary keys or set elements
- β Improve predictability, thread safety, and functional purity
π― In this guide, you’ll learn:
- What immutability means in Python
- Built-in immutable types
- How to create custom immutable data structures
- Third-party tools like namedtupleandpyrsistent
- Best practices and use cases
β What Does Immutable Mean in Python?
An immutable object is one whose state cannot change after it is created.
π¦ Built-in Immutable Types
| Type | Mutable? | Example | 
|---|---|---|
| int,float,str | β Immutable | x = 5,s = "hello" | 
| tuple | β Immutable | (1, 2, 3) | 
| frozenset | β Immutable | frozenset({1, 2, 3}) | 
| bytes | β Immutable | b"data" | 
π Example: Immutable tuple
data = (1, 2, 3)
data[0] = 10  # β TypeError: 'tuple' object does not support item assignment
β Tuples prevent accidental mutation.
π§± Immutable vs Mutable β Table Comparison
| Feature | Immutable Types | Mutable Types | 
|---|---|---|
| Can change after creation | β No | β Yes | 
| Hashable | β Yes | β Usually not | 
| Thread-safe | β Generally | β Without locks | 
| Safer in functions | β Yes | β Risk of side effects | 
π§° frozenset β Immutable Set
fset = frozenset([1, 2, 3])
fset.add(4)  # β AttributeError: 'frozenset' object has no attribute 'add'
β
 Use frozenset when you need a set but donβt want it modified.
π§ Creating Custom Immutable Structures
β
 Using namedtuple
from collections import namedtuple
Point = namedtuple("Point", "x y")
p = Point(10, 20)
print(p.x)  # 10
p.x = 5  # β AttributeError: can't set attribute
β Lightweight and immutableβperfect for read-only objects.
β
 Using @dataclass(frozen=True) in Python 3.7+
from dataclasses import dataclass
@dataclass(frozen=True)
class Config:
    host: str
    port: int
c = Config("localhost", 8080)
# c.port = 80  # β FrozenInstanceError
β Enforces immutability with a frozen dataclass.
π§ Third-Party Immutable Libraries
πΉ pyrsistent β Persistent/Immutable Data Structures
pip install pyrsistent
from pyrsistent import pvector
v = pvector([1, 2, 3])
v2 = v.append(4)
print(v)   # pvector([1, 2, 3])
print(v2)  # pvector([1, 2, 3, 4])
β Functional style: original structure is untouched.
πΉ immutables (by MagicStack)
pip install immutables
import immutables
mapping = immutables.Map({"a": 1})
new_map = mapping.set("b", 2)
print(mapping)   # immutables.Map({'a': 1})
print(new_map)   # immutables.Map({'a': 1, 'b': 2})
β Efficient and safe mapping for concurrent programs.
π§ Benefits of Immutability
| Benefit | Why It Matters | 
|---|---|
| Predictable behavior | No hidden side effects | 
| Safer concurrency | No need for locks on immutable objects | 
| Hashability | Can be used as keys in dicts or set items | 
| Reusability | Shared safely without copies | 
| Functional programming | Aligns with stateless, declarative style | 
π§ͺ Real-World Use Case β Safe Function Parameters
def process_data(data: tuple[int, int]):
    return data[0] + data[1]
result = process_data((10, 20))  # β
 Immutable input
β Functions that accept immutable inputs are safe from mutation bugs.
π Best Practices
| β Do This | β Avoid This | 
|---|---|
| Use tupleinstead oflistfor constants | Modifying global mutable defaults | 
| Use @dataclass(frozen=True)for configs | Using mutable dataclasses for read-only data | 
| Favor frozensetfor static sets | Using set()for constants | 
| Use third-party libraries for complex needs | Reinventing immutable containers | 
π Summary β Recap & Next Steps
Immutable data structures provide stability, safety, and performance benefits in Python. They prevent side effects and make your code easier to understand and test.
π Key Takeaways:
- β Tuples, strings, frozensets, and frozen dataclasses are immutable
- β
 Use namedtupleanddataclass(frozen=True)for simple records
- β
 Use libraries like pyrsistentandimmutablesfor advanced needs
- β Immutability improves safety, hashability, and concurrency
βοΈ Real-World Relevance:
Used in config systems, functional programming, safe APIs, data pipelines, and thread-safe code.
β FAQ β Immutable Data Structures in Python
β Is a Python list immutable?
β No. Lists are mutable and can be changed after creation.
β Are tuples always safe?
β Yes, as long as they donβt contain mutable objects inside.
β What is the difference between frozenset and set?
- frozensetis immutable
- setis mutable and can change at runtime
β Can I create immutable dictionaries?
β
 Yes. Use third-party libraries like immutables or custom MappingProxyType.
β Why is immutability useful in concurrency?
β Immutable objects are inherently thread-safeβthey can’t be changed, so no locking is required.
Share Now :
