Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python hash and equality: immutable dictionary keys

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A hashable dictionary key needs a hash that remains stable during its lifetime, and equal keys must produce equal hashes.

Download Python source kit

Operation contract

The receipt key has two immutable fields and value-based equality supplied by a frozen dataclass. Separately constructed equal keys retrieve the same ledger entry. The stored amount is not part of the key. Keeping identity separate from changing state avoids losing an entry after a field used by its hash changes.

Failure and ownership boundary

Frozen dataclasses prevent their normal field assignment; they do not recursively freeze nested objects. This key uses only a string and an integer. A class that defines equality without a suitable hash becomes unhashable. Hash collisions are legal: dictionary lookup still compares candidate keys. Python dictionaries: insertion order and duplicate-key replacement and Python dataclasses: frozen fields require an immutable value model explain the surrounding rules.

Working program

python
from dataclasses import dataclass

@dataclass(frozen=True)
class ReceiptKey:
    region: str
    sequence: int

ledger = {ReceiptKey("DEL", 41): 1250}
lookup_key = ReceiptKey("DEL", 41)
print(ledger[lookup_key])
print(hash(lookup_key) == hash(ReceiptKey("DEL", 41)))
try:
    ledger[["DEL", 41]] = 1250
except TypeError:
    print("mutable list rejected as key")

Output

Output
1250
True
mutable list rejected as key

Costs and limits

Dictionary operations have expected constant lookup work under suitable hash behavior, but collisions can require more comparisons. Computing a key hash also has field-dependent cost. Do not persist Python hash values as stable cross-process identifiers.

Common Mistakes

  • Equal keys must have equal hashes; unequal keys may also collide.
  • A frozen wrapper can still contain unsuitable mutable fields.

Connected lessons

Python dictionaries: insertion order and duplicate-key replacement, Python dataclasses: frozen fields require an immutable value model, Python sets: membership and deduplication do not preserve input order.

Follow the ownership and update boundary

Python rich comparison: return NotImplemented for unsupported operands.

Check this related boundary

Python interview: mutating a hash key breaks dictionary lookup assumptions.

Trace the next boundary

Python interview: bool and int can address the same dictionary key.

Follow the integrity boundary

Python interview: a tuple can be unhashable when it contains a list.

python
hash-equality
Storage details