What are hashable data types?
sobes.tech AI
Answer from AI
Hashable data types in Python are immutable types, whose instances have a fixed hash value throughout their lifetime. This value is computed using a hash function and is used for quick lookup of elements in sets and keys in dictionaries.
Properties of hashable types:
- Immutability: The object cannot be changed after creation.
- Presence of
__hash__method: This method should return an integer hash value of the object. If the method is not defined or returnsNone, the object is considered unhashable. - Presence of
__eq__method: This method should define object equality. If two objects are equal (a == b), then their hash values should be equal (hash(a) == hash(b)). The reverse is not necessarily true: two objects can have the same hash value but not be equal (hash collision).
Examples of built-in hashable types:
- Numbers (
int,float,complex):# Examples print(hash(123)) print(hash(3.14)) print(hash(1 + 2j)) - Strings (
str):# Example print(hash("hello")) - Tuples (
tuple): Provided all elements of the tuple are hashable.# Example print(hash((1, 2, "a"))) - Boolean values (
bool):# Example print(hash(True)) NoneType:# Example print(hash(None))
Examples of unhashable built-in types:
- Lists (
list): Mutable.# Example # list = [1, 2] # print(hash(list)) # Will raise TypeError - Sets (
set): Mutable.# Example # my_set = {1, 2} # print(hash(my_set)) # Will raise TypeError - Dictionaries (
dict): Mutable.# Example # my_dict = {"a": 1} # print(hash(my_dict)) # Will raise TypeError
Usage of hashable types:
- Dictionary keys must be hashable.
# Example my_dict = {"apple": 1, (1, 2): 2} # Allowed # my_dict = {[1, 2]: 3} # Not allowed, will raise TypeError - Set elements must be hashable.
# Example my_set = {"a", 1, (2, 3)} # Allowed # my_set = {"a", [1, 2]} # Not allowed, will raise TypeError
Custom classes are hashable by default if they inherit from a class that defines __hash__, or if they do not define __eq__ and __hash__. If only __eq__ is defined, the class becomes unhashable. You can make a custom class hashable by defining __eq__ and __hash__ methods that meet your requirements. For immutable objects, you can use the @total_ordering decorator along with defining __eq__ and other comparison methods.
# Example of a custom immutable and hashable class
from functools import total_ordering
@total_ordering
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __hash__(self):
# Hash of a tuple containing hashes of the elements
return hash((self.x, self.y))
# Usage in a dictionary
p1 = Point(1, 2)
p2 = Point(1, 2)
my_dict = {p1: "coordinates"}
print(p2 in my_dict) # True, because objects are equal and hashable