From f94ffa4a220e9bab5b85e37b3743983bc7fb108d Mon Sep 17 00:00:00 2001 From: sindhujapagadala Date: Tue, 28 Oct 2025 16:33:52 +0530 Subject: [PATCH] Create hashable_types.md --- docs/hashable_types.md | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 docs/hashable_types.md diff --git a/docs/hashable_types.md b/docs/hashable_types.md new file mode 100644 index 0000000..d6d0fbd --- /dev/null +++ b/docs/hashable_types.md @@ -0,0 +1,70 @@ +# Hashable Built-in Data Types + +**Hashable objects** have a hash value that never changes during their lifetime +and can be used as dictionary keys or set elements. +Objects are hashable by default if they are immutable and implement both +`__hash__()` and `__eq__()` consistently. + +--- + +## Hashable Built-in Types + +The following standard built-in types are hashable: + +- `int` +- `float` +- `complex` +- `bool` +- `str` +- `bytes` +- `tuple` *(only if all its elements are hashable)* +- `frozenset` +- `range` +- `NoneType` (`None`) +- `memoryview` *(if readonly)* +- user-defined classes that implement `__hash__` consistently with `__eq__` + +Most hashable types are immutable. + +Mutable built-in types such as `list`, `set`, and `dict` are **not** hashable +because their contents (and thus their hash values) can change. + +--- + +## Notes and Exceptions + +- Immutable objects have stable hash values → can be used as dictionary keys. +- Mutable objects can’t be hashed because their state (and equality) can change. +- A `tuple` is hashable **only if all its elements** are hashable. +- `memoryview` is hashable only if it’s **readonly**. +- User-defined classes are hashable by default **unless** `__eq__` is overridden + without redefining `__hash__`. + +--- + +## Quick Check in Python + +You can test hashability easily with this helper function: + +```python +def is_hashable(obj): + try: + hash(obj) + return True + except TypeError: + return False + +examples = [int, float, complex, bool, str, bytes, + tuple, list, dict, set, frozenset, range, + memoryview, type(None)] + +for t in examples: + # Safely create an instance + if t is memoryview: + instance = t(b"example") # readonly by default + elif t is type(None): + instance = None + else: + instance = t() + + print(f"{t.__name__:>10}: {is_hashable(instance)}")