Got a TypeError: unhashable type: 'dict'
error? You're probably trying to put a dictionary inside another dictionary as a key. Python doesn't allow this, but there are easy ways to get what you want.
What Does "Unhashable" Actually Mean?
Think of hashing like creating a unique fingerprint for an object. Just like your fingerprint never changes throughout your life, a hashable object in Python must have a value that never changes. Python uses these "fingerprints" (hash values) to quickly locate items in dictionaries and sets.
# These are hashable - they can be dictionary keys
my_dict = {
"name": "Alice", # String - hashable
42: "answer", # Integer - hashable
(1, 2, 3): "tuple" # Tuple - hashable
}
But dictionaries can change after you create them - you can add new items, remove items, or modify existing ones. Since they keep changing, Python can't create a reliable fingerprint for them:
# Dictionaries are unhashable because they can change
user_prefs = {"theme": "dark"}
user_prefs["notifications"] = "on" # We just changed it!
# Python can't use this as a dictionary key because it might change again
Seeing the Error in Action
The most common scenario is trying to use a dictionary as a key in another dictionary:
# This will throw the error
user_data = {
"name": "Alice",
{"preferences": "dark_mode"}: "enabled" # Dictionary as key - won't work!
}
This code produces the following error:
File "test.py", line 3, in <module>
{"preferences": "dark_mode"}: "enabled"
TypeError: unhashable type: 'dict'
You'll also see this error when:
- Adding dictionaries to sets
- Using dictionaries as keys in other dictionaries
- Passing dictionaries to functions that expect hashable types
The Quick Fix
Convert your dictionary to a tuple of its items:
# Working solution
user_data = {
"name": "Alice",
tuple({"preferences": "dark_mode"}.items()): "enabled"
}
Better Approaches for Real-World Code
While the tuple conversion works, it's often not the most readable solution. Here are some cleaner alternatives:
Option 1: Flatten Your Data Structure
Instead of trying to nest dictionaries as keys, restructure your data to use simple strings as keys. This approach is easier to read and work with in most cases.
# Instead of nested dictionaries as keys
user_settings = {
"name": "Alice",
"preference_theme": "dark_mode",
"preference_notifications": "enabled"
}
Option 2: Use String Keys
Convert the dictionary to a JSON string, which gives you a consistent string representation that can be used as a key. This preserves the original structure while making it hashable.
# Convert the dictionary to a string representation
import json
settings_key = json.dumps({"preferences": "dark_mode"}, sort_keys=True)
user_data = {
"name": "Alice",
settings_key: "enabled"
}
Option 3: Create a Custom Class
Build a custom class that can represent your data and be used as a dictionary key. This gives you the most control and makes your code more object-oriented.
class UserPreference:
def __init__(self, **kwargs):
self.data = tuple(sorted(kwargs.items()))
def __hash__(self):
return hash(self.data)
def __eq__(self, other):
return self.data == other.data
pref = UserPreference(theme="dark_mode")
user_data = {"name": "Alice", pref: "enabled"}
Understanding Related Errors
You might also encounter TypeError: unhashable type: 'dict_keys'
or TypeError: unhashable type: 'dict_values'
. These happen for the same reason – dict.keys()
and dict.values()
return view objects that aren't hashable either.
# This won't work
my_dict = {"a": 1, "b": 2}
problem_set = {my_dict.keys()} # Error!
# Convert to tuple first
working_set = {tuple(my_dict.keys())}
Debugging Tips
When you hit this error, ask yourself:
- Am I trying to use a dictionary as a key somewhere?
- Am I adding a dictionary to a set?
- Did I accidentally pass a dictionary where a hashable type was expected?
The stack trace will usually point you to the exact line where you're trying to use an unhashable object. And if you're dealing with a larger codebase and want better visibility into where these errors are happening, error monitoring tools like Rollbar can help you track down the exact context and frequency of these issues.
Putting It All Together
The TypeError: unhashable type: 'dict'
error is Python's way of telling you that you're trying to use something changeable (like a dictionary) in a place that needs something unchangeable (like a dictionary key). Once you understand this concept, you'll quickly spot these issues and know exactly how to fix them.
The key is choosing the right solution for your specific use case – sometimes it's as simple as restructuring your data, other times you might need a more sophisticated approach like a custom hashable class.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Python errors easier than ever. Try it today!