DEV Community

Coder
Coder

Posted on

TypeError: unhashable type: 'dict' in Python

Have you ever come across an error message that reads "TypeError: unhashable type: 'dict' in Python"? If yes, then you're not alone. This error occurs when you attempt to use a dictionary as the key of another dictionary or within a set. In this blog post, we will explore this error message in detail, understand what it means, and look at ways to fix it. So, let's get started.

The Error Message Explained

When you declare a dictionary in Python, it creates a unique hash value, which enables you to use it as a key in other dictionaries or sets. However, sometimes the information contained in a dictionary is not immutable. That is, the values it contains can be changed after it's created, making it impossible to generate a stable hash value. When this happens, Python raises a "TypeError: unhashable type: 'dict'" error message.

Common Causes of the "TypeError: unhashable type: 'dict' in Python"

This error message can be triggered by several factors, including:

1. Using a dictionary as a key of another dictionary

When you attempt to use a dictionary as the key of another dictionary, Python expects that the dictionary is immutable. For example:

dict1 = {}
dict2 = {dict1: "value"}
Enter fullscreen mode Exit fullscreen mode

In the above example, Python raises a TypeError because dict1 is mutable.

2. Using a dictionary within a set

Like a dictionary, a set requires its elements to be immutable so that they can be hashed. When you insert a dictionary into a set, and the dictionary's contents can be changed after creation, Python raises a TypeError. Here's an example:

set1 = set()
set2 = {set1, {}}
Enter fullscreen mode Exit fullscreen mode

Python raises TypeError because set1 is mutable.

3. Changing values in a dictionary used as a key

If you've used a dictionary as a key previously, and you then later modify it, Python won't be able to generate a consistent hash value, forcing it to raise a TypeError. Here's an example:

dict1 = {"key": "value"}
dict2 = {dict1: "value1"}
# Modify dict1 after it has been used as a key
dict1["key"] = "value2"
# Now try to use dict1 as a key again
dict3 = {dict1: "value2"}
Enter fullscreen mode Exit fullscreen mode

In the above example, Python raises TypeError on dict3 because dict1 has been changed since it was first used as a key.

4. Creating a dictionary with mutable values

When you create a dictionary, you should ensure that the values are immutable. If the values are mutable, and you later modify them, Python will raise a TypeError. Here's an example:

dict1 = {"key": []}
dict2 = {dict1: "value"}

# Now modify the mutable values in dict1
dict1["key"].append("value")

dict3 = {dict1: "value2"}
Enter fullscreen mode Exit fullscreen mode

In the example above, Python raises a TypeError on dict3 because one of the values in dict1 is mutable.

How to Fix the "TypeError: unhashable type: 'dict' in Python"

Now that we've seen some of the common causes of the "TypeError: unhashable type: 'dict' in Python," let's look at how we can resolve it.

1. Unpacking the dictionary into a tuple

One way to avoid the error is to unpack the dictionary into a tuple containing its key-value pairs, thus making it immutable. Here's an example:

dict1 = {}
tuple1 = tuple(dict1.items())
dict2 = {tuple1: "value"}
Enter fullscreen mode Exit fullscreen mode

In the above example, we've converted dict1 into a tuple containing its key-value pairs and used it as a key in dict2. This works because tuples are immutable, and the contents of dict1, which contains mutable elements, have been converted into an immutable tuple.

2. Using frozenset

Another way to ensure that the contents of a dictionary are immutable is to use frozenset. Here's an example:

dict1 = {}
frozenset1 = frozenset(dict1.items())
dict2 = {frozenset1: "value"}
Enter fullscreen mode Exit fullscreen mode

In this example, we've converted dict1 into a frozenset. The frozenset method takes an iterable and returns an immutable frozenset object. In our case, we've used the dict.items() method to convert dict1 into an iterable, which we've then passed to frozenset.

3. Creating a custom class

If the above methods don't work for you, you can create a custom class that implements the hash and eq methods. Here's an example:

class CustomDict:
    def __init__(self, items):
        self.items = items

    def __hash__(self):
        return hash(frozenset(self.items.items()))

    def __eq__(self, other):
        return isinstance(other, CustomDict) and self.items == other.items

dict1 = {}
custom_dict = CustomDict(dict1)
dict2 = {custom_dict: "value"}
Enter fullscreen mode Exit fullscreen mode

In this example, we've created a custom dictionary class that takes a dictionary as input and implements the hash and eq methods. The hash method returns a hash value, which is generated by converting the dictionary's key-value pairs into a frozenset and hashing it. The eq method compares the CustomDict objects and returns True if they have the same key-value pairs.

Final Thoughts

The "TypeError: unhashable type: 'dict' in Python" can be frustrating, especially if you don't understand what it means or how to fix it. However, by understanding the common causes of the error, you can take the necessary steps to resolve it. In this blog post, we've explored some of the ways to resolve the error, including unpacking the dictionary into a tuple, using frozenset, and creating a custom class. By implementing these solutions, you can avoid the TypeError and keep your code running smoothly.

Top comments (0)