DEV Community

Cover image for About "TypeError: unhashable type: ‘dict'” in Python
Reza Lavarian
Reza Lavarian

Posted on • Originally published at decodingweb.dev

About "TypeError: unhashable type: ‘dict'” in Python

Update: This post was originally published on my blog decodingweb.dev, where you can read the latest version for a 💯 user experience. ~reza

The “TypeError: unhashable type: ‘dict'” error occurs if you use a dictionary where a hashable object is expected.

Whether you’re learning to code, or you’re already a Pythonista, you might encounter this error if:

  • You use a dictionary as the key in another dictionary
  • You want to store a dictionary in a Python Set
  • You pass a dictionary to the hash() function

The error looks like this:

Traceback (most recent call last):
 File "", line 1, in 
TypeError: unhashable type: 'dict'
Enter fullscreen mode Exit fullscreen mode

As you can see, the error message is accompanied by the line number (under "traceback most recent call last file").

But what are hashable objects? You may ask.

Based on Python.org:

An object is hashable if it has a hash value that never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method). Hashable objects which compare equal must have the same hash value.

An unhashable object in Python can't have a fixed hash value that remains constant during its lifetime.

Python uses a hash value internally to efficiently look up items in a set or dictionary. When an unhashable object is added to a set or used as a key in a dictionary, a TypeError is raised because the object's hash value can change (when we add/remove items), making it impossible to retrieve the correct value from the set or dictionary.

Below are three facts to know about hashable objects in Python:

#1 Most of Python’s immutable built-in objects (strings, numeric values, etc.) are hashable.
#2 Immutable objects (such as tuples and frozensets) are only hashable if their elements are hashable.
#3 Mutable containers such as lists or dictionaries aren't hashable.

Simply put, Python "typeerror unhashable type" occurs whenever you use a dictionary or list where Python expects a string or numeric value.

Similarly, if you use a list as a key, you would get the "TypeError: unhashable type: 'list'" error. Just like dictionaries, lists are mutable.

How to fix TypeError: unhashable type: 'dict' in Python

If you're getting this error while using a dictionary as a key in another dictionary, give your design decision a second thought!

Ask you yourself why do you need to use the whole dictionary as a key? Sometimes you can pluck a value out of that dictionary and use it as the key.

Imagine we have a list object that contains multiple dictionaries. These dictionaries contain information about programming books in a bookstore.

We also have an inventory dictionary, which we want to initialize with 10 items per book.

You might want to do it like so:

books = [
   { 
      'title': 'Elquent JavaScript',
      'isbn': '9781593279509' 
   },
   { 
      'title': 'Learning Python',
      'isbn': '9781449355739'
   },
   { 
      'title': 'Head First Python',
      'isbn': '9781491919538'
   }
]

inventory = {}

for book in books:
  inventory[book] = 10
Enter fullscreen mode Exit fullscreen mode

The above code would raise the TypeError because the book variable in each iteration is a dict object.

But what if we could take each book's unique ISBN and use it as the key?

# books = ...

inventory = {}

for book in books:
  inventory[book['isbn']] = 10

print(inventory)
# output: {'9781593279509': 10, '9781449355739': 10, '9781491919538': 10}
Enter fullscreen mode Exit fullscreen mode

Well, that's much better! And we won't get the error.

However, if you really need to use a Python dictionary as the key, you must make it hashable first - by converting the dictionary to a tuple.

Here's how you would do it with a tuple:

inventory = {}

for book in books:
  book_hash = tuple(book.items())
  inventory[book_hash] = 10
Enter fullscreen mode Exit fullscreen mode

If you have a list, you can also convert the list to a tuple to make it hashable.

This works, if that's what you want! There's a catch, though!

We can only use tuples (or frozensets) if items in the dictionary are all hashable. If the dictionary contains sub-dictionaries, we might have to take a recursive approach to make it hashable.

Once your dictionaries become hashable, you can store them in Python sets too.

Problem solved 👍.

Alright, that does it! I hope this quick guide helped you fix your problem.

Thanks for reading.


❤️ You might like:

Top comments (0)