Python Dictionaries Require Hashable Keys
Posted by Aly Sivji in Quick Hits
I was floored when I discovered I could use tuples (and namedtuples) as Python dictionary keys.
Turns out this is not totally correct.
Started reading Fluent Python and learned that tuples are not always immutable. For instance, they can contain list elements...
my_tuple = ('a', 'b', [1, 2])
type(my_tuple)
Let's try using my_tuple
as a dictionary key.
# First we'll create a dictionary and insert a (key, value) pair
my_dict = {}
my_dict['test'] = 'foo'
my_dict
# Let's make sure that we cannot use a list element in the dictionary
my_dict[[1, 2]] = 'foo'
# Dictionary has not changed
my_dict
# Let's try inserting a tuple containing a list, as a key
my_dict[my_tuple] = 'bar'
This should be true for namedtuples
as well.
from collections import namedtuple
TestTuple = namedtuple('TestTuple', ['field1', 'field2', 'field3'])
my_item = TestTuple('a', 'b', [1, 2])
type(my_item)
isinstance(my_item, tuple)
my_dict[my_item] = 'bar'
What's going on?
Python dictionaries leverage hash tables. When we use a key that contains an unhashable type, i.e. a list, the underlying hash map cannot guarantee the key will map to the same bucket every single time. If we can't hash our key, we can't use it in our dictionary.
Therefore, Python dictionaries require hashable dict keys. Having immutable keys is not enough.
Shoutout to Luciano Ramalho for writing Fluent Python. Only three chapters in and this kind of thinking is becoming second nature.
Comments