What is a Mutable, Immutable, Hash?

Notes on hashability.

Mutable objects in Python can change their value but retain their id().

A set can be modified after creation using its methods. The name s is a reference to an instance of the set class, the value of which is a collection of numbers.

s = {1, 2, 3}
print(id(s))
# 2479855327872

s.add(4)
print(s)
# {1, 2, 3, 4}

print(id(s))
# 2479855327872

Immutable is an object with a fixed value. We cannot update the value of an immutable object. If you want to use a different value, you create a new object. Immutable objects do not have methods for adding new values or changing existing values.

Tuples allow concatenation with objects of the same type. But the name t now refers to a new instance of the tuple class with a different value.

t = (1, 2, 3)
print(id(t))
# 2479855652736

t += (4,)
print(t)
# (1, 2, 3, 4)

print(id(t))
# 2479850836256

A hashable object is an object that has a hash value and can be compared with other objects. Hash values are integers. The hash value of an object remains unchanged during its lifetime.

Immutable objects are usually hashable. In this case, the hash value of the object depends on its value. Since the value cannot change, this ensures the consistency of the hash value.

If an object is mutable, we cannot rely on its value. Mutable containers such as list, dict, set, bytearray, and instances of derived classes have __hash__ method set to None.

d = {}

print(d.__hash__)
# None

User-defined classes and class instances are hashable by default. However, a custom class can override the __hash__ method for calculating a hash and the __eq__ method for equality comparison. Some PSL classes define their hash functions and override the __hash__ method.

Modules, functions, class instances and classes themselves, have a hash value derived from their id().


Hash for different types (see references):

There are certain hash calculation rules for numeric types.
For strings and bytes, see PEP 456 (SipHash).
Some built-in types, such as tuples, have a separate algorithm.

References:

  1. Docs: hashable
  2. Docs: object.__hash__
  3. Docs: hash(object)
  4. Docs: Hashing of numeric types
  5. PEP 456 – default string and bytes hash algorithm
  6. GitHub: pyhash.c
  7. GitHub: Hash for tuples, tupleobject.c

Popular posts from this blog