Skip to content

/errors/python/typeerror-unhashable-type-list

TypeError: unhashable type: 'list'

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · Python 3.13.15updated
tool
Python
exit code
1
versions
Python 3.x
os
any

TypeError: unhashable type: 'list' means a list was used where Python needs a hashable value: as a dictionary key, as a set member, or as an argument to a function that hashes its arguments. Lists are mutable, so they have no stable hash. Use a tuple instead, or move the list to the value side of the dictionary.

Reproduce it

bash
cat > app.py <<'EOF'
d = {[1, 2]: "pair"}
EOF
python app.py

Output · exit 1

Traceback (most recent call last):
  File "/tmp/work/app.py", line 1, in <module>
    d = {[1, 2]: "pair"}
        ^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'list'

The same error appears for set([[1, 2], [3]]) and for {1, [2]}.

Fixes

bash
cat > fix.py <<'EOF'
d = {(1, 2): "pair"}                       # tuple as key
print(d[(1, 2)])
rows = [[1, 2], [3], [1, 2]]
print(sorted(set(map(tuple, rows))))        # unique rows
print({frozenset([1, 2]): "unordered"})     # order does not matter
print({"pair": [1, 2]})                     # list as value
EOF
python fix.py

Output

pair
[(1, 2), (3,)]
{frozenset({1, 2}): 'unordered'}
{'pair': [1, 2]}
TypeHashable
int, float, str, bytes, bool, Noneyes
tuple, frozensetyes, if all items are hashable
list, dict, setno

A tuple that contains a list is also unhashable: hash(([1], 2)) raises the same error.

Less obvious places

The error is not limited to dictionary literals. These operations hash their argument too:

CodeWhy it hashes
d[[1, 2]] = 1 or d.get([1, 2])Dictionary keys are looked up by hash
s.add([3]), set(list_of_lists)Set members must be hashable
[1] in {1, 2}Membership in a set or dict hashes the left side
A function decorated with functools.lru_cache called with a listThe cache key is built from the arguments
Counter(list_of_lists), dict.fromkeys(list_of_lists)Each item becomes a key

The traceback shows the line; on Python 3.11 and later the carets point at the exact expression that was hashed.

Cached functions

functools.lru_cache requires hashable arguments. Convert lists to tuples at the call site, or add a thin wrapper that does it:

bash
cat > cache.py <<'EOF'
from functools import lru_cache

@lru_cache
def total(items):
    return sum(items)

try:
    total([1, 2, 3])
except TypeError as e:
    print("list:", e)
print("tuple:", total((1, 2, 3)))
EOF
python cache.py

Output

list: unhashable type: 'list'
tuple: 6

Prevent it

Choose immutable types for anything used as an identifier: tuples for composite keys such as (x, y) coordinates, frozensets for unordered groups, and strings or numbers for IDs. When data arrives as JSON, arrays become lists, so convert them before using them as keys.

FAQ

Why can a tuple be a dictionary key but a list cannot?

A dictionary finds keys by their hash, so a key must keep the same hash for its whole life. A list can change after it is stored, which would make the entry unreachable, so lists define no hash. Tuples are immutable and hash their items.

What about unhashable type: 'dict' or 'set'?

It is the same error for the other built-in mutable containers. Convert a set to a frozenset, and a dict to something immutable such as tuple(sorted(d.items())) when its values are hashable.

How do I remove duplicate lists from a list while keeping order?

Track what you have seen as tuples: seen = set(); keep only the rows whose tuple(row) is not in seen, adding it as you go. dict.fromkeys(map(tuple, rows)) also keeps the first occurrence in order.

Sources