Immutable Collections
The `immutables` library for Python provides a high-performance immutable mapping type, `immutables.Map`, built on a Hash Array Mapped Trie (HAMT) data structure. It offers efficient (O(log N)) operations for setting and getting values, making it suitable for functional programming paradigms and scenarios where data integrity and thread safety are paramount. The current version is 0.21. It follows a release cadence driven by bug fixes and performance improvements.
Warnings
- gotcha This `immutables` library provides an immutable *mapping type* (`immutables.Map`), not a decorator for creating immutable classes. There is a different Python library (`python-immutable`) and a popular Java library (also named `Immutables`) with similar names but different functionality.
- breaking Direct mutation of `immutables.Map` instances is not supported and will raise errors. Operations like `my_map['key'] = value` or `del my_map['key']` directly on an `immutables.Map` object are invalid.
- gotcha While often performing like O(1) for practical purposes, operations like `set()` and `get()` on `immutables.Map` are theoretically O(log N) due to its Hash Array Mapped Trie (HAMT) data structure. This can be a consideration for extremely large maps or highly performance-sensitive loops compared to Python's built-in `dict` (average O(1)).
- gotcha For multiple consecutive modifications to an `immutables.Map`, chaining `set()` or `delete()` calls can be inefficient as each operation creates a new intermediate `Map` object. This can lead to increased memory allocation and performance overhead.
Install
-
pip install immutables
Imports
- Map
import immutables my_map = immutables.Map()
Quickstart
import immutables
# Create an immutable map
my_map = immutables.Map({"a": 1, "b": 2})
print(f"Original Map: {my_map}")
# Set a value (returns a *new* map)
new_map = my_map.set("c", 3)
print(f"Map after setting 'c': {new_map}")
print(f"Original map is unchanged: {my_map}")
# Delete a value (returns a *new* map)
map_after_delete = new_map.delete("b")
print(f"Map after deleting 'b': {map_after_delete}")
# Batch mutations using a context manager for efficiency
with my_map.mutate() as mutable_map:
mutable_map["d"] = 4
del mutable_map["a"]
mutable_map["e"] = 5
batch_mutated_map = mutable_map.finish()
print(f"Map after batch mutations: {batch_mutated_map}")