Python
Dictionary Keys
Immutable Types
List as Key
Hashable Objects

Why can't I use a list as a dict key in python? Exactly what can and cannot be used, and why?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Dictionary lookups are fast because Python hashes the key and uses that hash to locate the value. That only works if a key has a stable hash and a consistent equality rule. Lists do not satisfy that contract, which is why Python refuses to use them as dictionary keys.

Keys Must Be Hashable

An object is usable as a dictionary key when it is hashable. In practice that means:

  • it provides a __hash__() result
  • its hash stays stable while the object is used as a key
  • its __eq__() behavior is compatible with that hash

That is why immutable built-ins are common keys. Their value does not change after creation, so their hash remains meaningful.

python
1data = {
2    "name": "Ada",
3    42: "answer",
4    (2025, 9): "release",
5    frozenset({"red", "blue"}): "palette",
6}
7
8print(data[(2025, 9)])

Why Lists Cannot Be Used

Lists are mutable. If Python allowed a list to be a dictionary key, you could insert the key and then modify its contents, which would make the original hash-based placement unreliable.

python
1values = [1, 2, 3]
2
3try:
4    mapping = {values: "not allowed"}
5except TypeError as exc:
6    print(exc)

That raises TypeError: unhashable type: 'list'.

The real rule is not simply "lists are mutable". The deeper rule is "dictionary keys must remain hash-consistent". Mutability usually breaks that guarantee, so mutable containers are unhashable by design.

What Can and Cannot Be Keys

Common valid key types include:

  • 'str'
  • 'int'
  • 'float'
  • 'bool'
  • 'tuple of hashable values'
  • 'frozenset'

Common invalid key types include:

  • 'list'
  • 'dict'
  • 'set'

Tuples are only hashable if every element inside them is hashable:

python
1good = {(1, 2, 3): "ok"}
2print(good[(1, 2, 3)])
3
4try:
5    bad = {([1, 2], 3): "fails"}
6except TypeError as exc:
7    print(exc)

The second case fails because the tuple contains a list, and hashability depends on the contents too.

Convert Mutable Structure into an Immutable Key

If your logical key is "a sequence of values", the usual fix is to convert the list into a tuple before using it as a key.

python
1path = ["users", "42", "settings"]
2cache = {}
3
4cache[tuple(path)] = {"theme": "dark"}
5print(cache[("users", "42", "settings")])

If order should not matter, frozenset is often a better fit:

python
permissions = frozenset({"read", "write"})
roles = {permissions: "editor"}
print(roles[permissions])

Custom Objects Can Be Dictionary Keys

User-defined objects can also be keys if they obey the same hash-and-equality rules. A frozen dataclass is one convenient way to get that behavior.

python
1from dataclasses import dataclass
2
3@dataclass(frozen=True)
4class Coordinate:
5    x: int
6    y: int
7
8points = {Coordinate(2, 3): "origin-shifted"}
9print(points[Coordinate(2, 3)])

Because the object is frozen, the fields that determine equality do not change after creation.

Common Pitfalls

  • Thinking immutability is the only rule when the real requirement is hash consistency.
  • Assuming every tuple is hashable even if it contains a list, dict, or set.
  • Converting a list to a string for a key instead of using a structurally meaningful type like tuple.
  • Using mutable custom objects as keys and then changing fields that affect equality.
  • Forgetting that equal objects must produce equal hash values in custom classes.

Summary

  • Dictionary keys must be hashable and equality-stable.
  • Lists are unhashable because they are mutable and would break hash consistency.
  • Strings, numbers, tuples of hashable items, and frozenset are common valid keys.
  • If you need a sequence key, convert the list to a tuple.
  • Custom objects can be keys when their hash and equality behavior remain stable.

Course illustration
Course illustration

All Rights Reserved.