Skip to content

[Edit]: Python hash() #7197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 147 additions & 29 deletions content/python/concepts/built-in-functions/terms/hash/hash.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,181 @@
---
Title: 'hash()'
Description: 'Returns the hash value as a fixed sized integer.'
Description: 'Returns the hash value of an object for efficient dictionary key comparisons and data retrieval operations.'
Subjects:
- 'Data Science'
- 'Computer Science'
- 'Data Science'
Tags:
- 'Integers'
- 'Data Structures'
- 'Functions'
- 'Input'
- 'Hashes'
- 'Methods'
CatalogContent:
- 'learn-python-3'
- 'paths/computer-science'
---

The built-in **`hash()`** function returns a fixed-size integer hash value for an object, such as numbers, strings, tuples, or custom objects implementing the `__hash__()` method. Using type-specific algorithms, it facilitates efficient dictionary key comparisons during lookups. It can be used directly without requiring any imports.
The **`hash()`** function is a built-in Python function that returns the hash value of an object if it has one. Hash values are integers that are used to quickly compare dictionary keys during lookups, making data retrieval operations more efficient. The `hash()` function facilitates efficient dictionary key comparisons and is essential for implementing hashable collections like sets and dictionary keys.

The `hash()` function works with hashable objects such as numbers, [strings](https://www.codecademy.com/resources/docs/python/strings), [tuples](https://www.codecademy.com/resources/docs/python/tuples), and custom objects that implement the `__hash__()` method. It plays a crucial role in Python's internal data structures and is commonly used for data integrity checks, caching mechanisms, and creating unique identifiers for objects.

## Syntax

```pseudo
hash(object)
```

The `hash()` function takes a single argument, `object`, which represents the object from which to obtain the hash value.
**Parameters:**

The `object` can be of any hashable type, such as numbers, strings, tuples, or custom objects that implement the `__hash__()` method.
- `object`: The object for which to calculate the hash value. The object must be hashable (immutable types like numbers, strings, tuples, or custom objects implementing `__hash__()`).

## Example
**Return value:**

The example below defines a class called `MyClass`, with an attribute called `value`. The `__hash__()` method is implemented to customize the hashing behavior based on the `value` attribute.
The `hash()` function returns an integer representing the hash value of the object. If the object is not hashable, it raises a `TypeError`.

Two instances of `MyClass`, `obj1` and `obj2`, are created with different values. The `hash()` function is used to calculate the hash values of these objects. These values are then printed to the console.
## Example 1: Basic Hash Calculation

This example demonstrates how to customize the hash function for a custom class using the `__hash__()` method.
This example demonstrates how to calculate hash values for different data types including integers, strings, and floats:

```py
# Define a class
class MyClass:
def __init__(self, value):
self.value = value
# Hash different data types
number = 42
text = "Python Programming"
decimal = 3.14159

# Calculate hash values
number_hash = hash(number)
text_hash = hash(text)
decimal_hash = hash(decimal)

# Display the results
print(f"Hash of {number}: {number_hash}")
print(f"Hash of '{text}': {text_hash}")
print(f"Hash of {decimal}: {decimal_hash}")
```

The output of this code is:

```shell
Hash of 42: 42
Hash of 'Python Programming': -1234567890123456789
Hash of 3.14159: 1234567890987654321
```

def __hash__(self):
return hash(self.value)
> **Note:** These are placeholder values. Hash values for strings and floats can vary between runs due to hash randomization.

# Create instances of MyClass
obj1 = MyClass(42)
obj2 = MyClass("Hello")
This example shows that `hash()` works with various immutable data types. Notice that integers often return themselves as hash values for small numbers, while strings and floats produce larger hash values.

# Check the hash values
print(hash(obj1))
print(hash(obj2))
## Example 2: Hashable vs Non-Hashable Objects

This example illustrates the difference between hashable and non-hashable objects, demonstrating why some objects can be hashed while others cannot:

```py
# Hashable objects (immutable)
hashable_tuple = (1, 2, 3, "hello")
hashable_string = "Python"
hashable_number = 100

# Calculate hash for hashable objects
print(f"Tuple hash: {hash(hashable_tuple)}")
print(f"String hash: {hash(hashable_string)}")
print(f"Number hash: {hash(hashable_number)}")

# Non-hashable objects (mutable)
mutable_list = [1, 2, 3]
mutable_dict = {"key": "value"}

# Attempting to hash mutable objects will raise TypeError
try:
print(f"List hash: {hash(mutable_list)}")
except TypeError as e:
print(f"Error hashing list: {e}")

try:
print(f"Dict hash: {hash(mutable_dict)}")
except TypeError as e:
print(f"Error hashing dictionary: {e}")
```

## Codebyte Example
The output of this code is as follows:

```shell
Tuple hash: -1815842884691876695
String hash: -8264853706715907173
Number hash: 100
Error hashing list: unhashable type: 'list'
Error hashing dictionary: unhashable type: 'dict'
```

This example demonstrates that only immutable objects can be hashed. Mutable objects like lists and dictionaries raise a `TypeError` when passed to the `hash()` function because their contents can change, which would invalidate their hash values.

## Codebyte Example: Custom Object Hashing

In the example below, we define `my_tuple` as `(1, 2, 3)`. Subsequently, we use the `hash()` function to obtain the hash value of the input `my_tuple`. Then, we print the output of the `hash()` function.
This example shows how to implement custom hashing behavior for user-defined classes by overriding the `__hash__()` and `__eq__()` methods:

```codebyte/python
my_tuple = (1, 2, 3)
hash_value = hash(my_tuple)
print(hash_value)
```py
class Student:
def __init__(self, name, student_id, grade):
self.name = name
self.student_id = student_id
self.grade = grade

def __hash__(self):
# Create hash based on immutable attributes
return hash((self.name, self.student_id))

def __eq__(self, other):
# Define equality for proper hash behavior
if isinstance(other, Student):
return (self.name == other.name and
self.student_id == other.student_id)
return False

def __repr__(self):
return f"Student('{self.name}', {self.student_id}, '{self.grade}')"

# Create student objects
student1 = Student("Alice Johnson", 12345, "A")
student2 = Student("Bob Smith", 54321, "B")
student3 = Student("Alice Johnson", 12345, "A+") # Same name and ID

# Calculate and display hash values
print(f"Student 1 hash: {hash(student1)}")
print(f"Student 2 hash: {hash(student2)}")
print(f"Student 3 hash: {hash(student3)}")

# Check if students with same name and ID have same hash
print(f"Student 1 == Student 3: {student1 == student3}")
print(f"Same hash values: {hash(student1) == hash(student3)}")

# Use students as dictionary keys
student_grades = {
student1: "Excellent",
student2: "Good"
}

print(f"Grades dictionary: {student_grades}")
```

This example demonstrates proper implementation of custom hashing. The `__hash__()` method uses only immutable attributes (name and student_id), while the `__eq__()` method ensures that objects comparing as equal have the same hash value, which is required for correct behavior in hash-based collections.

## Frequently Asked Questions

### 1. Is there a built-in hash table in Python?

Yes, Python's `dict` (dictionary) is implemented as a hash table internally. Dictionaries use hash values of keys for fast lookups, insertions, and deletions. The `hash()` function is used internally to compute these hash values.

## 2. Does Python have a built-in hashmap?

Python's `dict` type serves as the built-in hashmap implementation. It provides O(1) average-case time complexity for key operations and automatically handles hash collisions and table resizing.

## 3. Can I hash mutable objects in Python?

No, mutable objects like lists, dictionaries, and sets cannot be hashed directly because their contents can change, which would invalidate their hash values. Only immutable objects can be safely hashed.

## 4. Why do hash values change between Python sessions?

Python uses hash randomization by default for security reasons. This means hash values for strings and other objects may differ between program runs, but they remain consistent within a single session.

## 5. How can I make my custom class hashable?

Implement both `__hash__()` and `__eq__()` methods in your class. The `__hash__()` method should return an integer based on immutable attributes, and objects that compare as equal must have the same hash value.