Firstly, we have a normal list:
ingredients = ["hot water", "taste"]
Trying to print this list's hash will expectedly raise a TypeError:
print(hash(ingredients))
>>> TypeError: unhashable type: 'list'
which means we cannot use it as a dictionary key, for example.
But now suppose we have a Tea
class which only takes one argument; a list.
class Tea:
def __init__(self, ingredients: list|None = None) -> None:
self.ingredients = ingredients
if ingredients is None:
self.ingredients = []
Surprisingly, creating an instance and printing its hash will not raise an error:
cup = Tea(["hot water", "taste"])
print(hash(cup))
>>> 269041261
This hints at the object being hashable (although pretty much being identical to a list in its functionality). Trying to print its ingredients
attribute's hash, however, will raise the expected error:
print(hash(cup.ingredients))
>>> TypeError: unhashable type: 'list'
Why is this the case? Shouldn't the presence of the list — being an unhashable type — make it impossible to hash any object that 'contains' a list? For example, now it is possible to use our cup
as a dictionary key:
dct = {
cup = "test"
}
despite the fact that the cup is more or less a list in its functionality. So if you really want to use a list (or another unhashable type) as a dictionary key, isn't it possible do do it in this way? (not my main question, just a side consequence)
Why doesn't the presence of the list make the entire datatype unhashable?