Python3 Func Hash
## Python hash() Function
The `hash()` function is a built-in Python function used to return the hash value of an object (if it has one).
A hash value is a fixed-size integer used to quickly compare dictionary keys and set elements during lookups. Objects that can be hashed are referred to as **hashable**. Generally, immutable built-in objects (such as strings, numbers, and tuples) are hashable, while mutable containers (such as lists, dictionaries, and sets) are not.
---
## Syntax and Parameters
### Syntax
```python
hash(object)
```
### Parameters
* **`object`**: The object whose hash value you want to calculate. This can be any object, but it must be hashable (i.e., it must implement the `__hash__()` magic method).
### Return Value
* Returns an **integer** representing the hash value of the object.
* If two objects compare as equal, their hash values must also be equal (e.g., `hash(1) == hash(1.0)`).
---
## Code Examples
### Example 1: Basic Usage with Built-in Types
This example demonstrates how `hash()` behaves with different built-in data types, including numbers, strings, tuples, and lists.
```python
# 1. Numeric types
print(hash(1)) # Output: 1 (Integers hash to themselves)
print(hash(3.14)) # Output: 314159 (or another calculated integer)
print(hash(-100)) # Output: -100
# 2. Strings (Note: String hashes are randomized per Python process for security)
print(hash("hello")) # Output: A large integer (e.g., -5678123456789)
print(hash("world")) # Output: Another large integer
# 3. Tuples (Immutable and hashable if all elements inside are hashable)
print(hash((1, 2, 3))) # Output: A calculated integer hash
# 4. Lists (Mutable and NOT hashable)
# print(hash([1, 2, 3]))
# Un-commenting the line above will raise: TypeError: unhashable type: 'list'
```
---
### Example 2: Usage in Dictionaries and Sets
Python's `dict` and `set` types rely internally on hash tables. This means their keys (for dictionaries) and elements (for sets) must be hashable.
```python
# Dictionary keys must be hashable
d = {"name": "Tom", "age": 20}
print(d) # Output: Tom
# Set elements must be hashable
s = {1, 2, 3, "hello"}
print(3 in s) # Output: True (Uses O(1) hash lookup)
# Custom class with __hash__ implemented
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# Implementing __hash__ allows custom objects to be hashable
def __hash__(self):
return hash((self.x, self.y))
# It is highly recommended to also implement __eq__ when implementing __hash__
def __eq__(self, other):
return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)
p = Point(1, 2)
print(hash(p)) # Output: A calculated integer hash based on the coordinates
```
---
## Key Considerations
### 1. Hash Seed Randomization
For security reasons (to prevent Denial of Service attacks targeting hash collisions), Python randomizes the hash values of strings, bytes, and datetime objects. This means that while `hash("hello")` remains constant within a single running Python process, it will change every time you restart Python.
### 2. Hashability vs. Mutability
* **Hashable objects** must have a hash value that never changes during their lifetime (requiring an `__hash__()` method) and must be comparable to other objects (requiring an `__eq__()` method).
* Most immutable built-in objects (like `str`, `bytes`, `numeric types`, `tuple`, `frozenset`) are hashable.
* Mutable containers (like `list`, `dict`, `set`) are **not** hashable and will raise a `TypeError` if passed to `hash()`.
### 3. Custom Classes
By default, user-defined classes are hashable. Their hash value is derived from their memory address (`id()`), and they compare unequal unless they are the exact same object. If you override `__eq__` in a custom class, Python implicitly sets `__hash__ = None`, making instances of the class unhashable. If you want your class to remain hashable after overriding `__eq__`, you must explicitly implement a custom `__hash__()` method as shown in Example 2.
YouTip