Last updated: Apr 8, 2024
Reading timeยท3 min
The Python "TypeError: unhashable type: 'set'" occurs when we use a set
as a
key in a dictionary or an element in another set
.
To solve the error, use a frozenset
instead because set
objects are
mutable and unhashable.
Here is an example of how the error occurs when using a set
as an element in
another set
.
my_set = {'apple', 'banana'} # ๐๏ธ using a set as an element in another set # โ๏ธ TypeError: unhashable type: 'set' another_set = {'Alice', 'Bobby', my_set}
And here is another example of how the error occurs when using a set
as a key
in a dictionary.
my_set = {'apple', 'banana'} # ๐๏ธ using a set as a key in a dictionary # โ๏ธ TypeError: unhashable type: 'set' my_dict = {my_set: 'fruits'}
set
as a key in a dictionary or as an element in another set
because set
objects are mutable and unhashable.frozenset
instead of a regular set
One way to solve the error is to use a frozenset
.
my_set = frozenset({'apple', 'banana'}) another_set = {'Alice', 'Bobby', my_set} print(another_set) # ๐๏ธ {'Bobby', frozenset({'banana', 'apple'}), 'Alice'} # checking if an element is in a set print(frozenset({'apple', 'banana'}) in another_set) # ๐๏ธ True # --------------------------------------------------------------- my_dict = {my_set: 'fruits'} print(my_dict) # ๐๏ธ {'Bob', frozenset({'banana', 'apple'}), 'Alice'} # ๐๏ธ accessing a key in the dictionary print(my_dict[frozenset({'apple', 'banana'})]) # ๐๏ธ fruits
We used a frozenset
instead of a set
. The frozenset
class takes an iterable as an argument.
frozenset
is an immutable version of the Python set
object, so it can be used as a key in a dictionary or an element in another set.Notice that you have to use the same approach to access the key in the dictionary.
tuple
instead of a set
objectAlternatively, you can use another immutable type such as a tuple
if that
suits your use case.
my_tuple = tuple({'apple', 'banana'}) my_set = {'Alice', 'Bobby', my_tuple} print(my_set) # ๐๏ธ {'Alice', 'Bobby', ('banana', 'apple')} print(tuple({'apple', 'banana'}) in my_set) # ๐๏ธ True # ----------------------------------------------------- my_dict = {my_tuple: 'fruits'} print(my_dict) # ๐๏ธ {('banana', 'apple'): 'fruits'} print(my_dict[tuple({'apple', 'banana'})]) # ๐๏ธ 'fruits'
Tuple objects are immutable and are hashable.
You can also declare a tuple directly by wrapping the items in parentheses and not square brackets.
my_tuple = ('a', 'b', 'c') print(my_tuple) # ๐๏ธ ('a', 'b', 'c') print(type(my_tuple)) # ๐๏ธ <class 'tuple'>
Most of the immutable built-in objects in Python are hashable, whereas mutable objects are unhashable.
set
, because these data structures use the hash value internally.Hashable objects include - str
,
int, bool
, tuple
,
frozenset
.
Unhashable objects include - list
, dict
, set
.
Note that tuples
and frozensets
are only hashable if their elements are
hashable.
You can check if an object is hashable by passing it to the built-in hash()
function.
print(hash('bobybhadz')) # ๐๏ธ -5394383801093474825 # โ๏ธ TypeError: unhashable type: 'set' print(hash({'bobby', 'hadz', 'com'}))
The hash() function returns the hash value of the passed-in object (if it has one).
Hash values are integers and are used to compare dictionary keys during a dictionary lookup.
Objects like sets are mutable because the contents of a set
can be changed.
my_set = {'a', 'b'} my_set.add('c') print(my_set) # ๐๏ธ {'c', 'a', 'b'}
On the other hand, frozenset
objects and tuples that contain primitive values
are immutable (and hashable).
Dictionaries are indexed by keys and the keys in a dictionary can be any immutable type, e.g. strings or numbers.
If a frozenset
or a tuple contains mutable objects such as lists, it cannot be
used as a key in a dictionary or an element in a set
.
If you aren't sure what type of object a variable stores, use the type()
class.
my_set = {'a', 'b'} print(type(my_set)) # ๐๏ธ <class 'set'> print(isinstance(my_set, set)) # ๐๏ธ True my_tuple = ('a', 'b') print(type(my_tuple)) # ๐๏ธ <class 'tuple'> print(isinstance(my_tuple, tuple)) # ๐๏ธ True
The type class returns the type of an object.
The isinstance() function
returns True
if the passed-in object is an instance or a subclass of the
passed in class.
You can learn more about the related topics by checking out the following tutorials: