Sobes.tech
Junior

¿Qué es un hash y cómo se usa en los diccionarios en Python?

sobes.tech AI

Respuesta de la IA

Hash (o valor hash) es un valor numérico de longitud fija calculado a partir del contenido de un objeto mediante una función hash. Una buena función hash garantiza la determinación (el mismo objeto siempre produce el mismo hash) y busca una distribución uniforme de los hashes para diferentes objetos.

En Python, los diccionarios (tipo dict) utilizan hashing para almacenar y buscar eficientemente pares de "clave-valor". Las claves en un diccionario deben ser hashables, es decir, tener el método __hash__() y ser inmutables o tener una implementación de __eq__() y __hash__() que garantice que objetos iguales por __eq__ tengan el mismo hash.

Proceso de funcionamiento de un diccionario con hashes:

  1. Inserción: Al agregar un par (clave, valor), se calcula el hash de la clave. Basándose en el hash, se determina un lugar aproximado (cesta o "bucket") para almacenar este par en memoria. Si varias claves tienen el mismo hash (colisión), los pares se almacenan en esa cesta, a menudo en forma de lista enlazada u otro mecanismo de resolución de colisiones.
  2. Búsqueda: Al buscar un valor por clave, se calcula el hash de la clave proporcionada. Usando el hash, el diccionario encuentra rápidamente la cesta correspondiente. Luego, dentro de esa cesta, se comparan las claves (usando el método __eq__) para encontrar la clave correcta y obtener su valor asociado.

Ventajas del uso de hashing:

  • Eficiencia: En promedio, las operaciones de inserción, eliminación y búsqueda en un diccionario se realizan con una complejidad temporal constante O(1), independientemente del tamaño del diccionario.
  • Acceso rápido: El hash permite acceder rápidamente a la ubicación prevista de los datos, evitando recorrer todos los elementos.

Limitaciones y características:

  • Claves hashables: Como se mencionó, las claves deben ser hashables. Tipos mutables, como listas (list) y conjuntos (set), no son hashables por defecto y no pueden usarse como claves en un diccionario.
  • Colisiones: Aunque las funciones hash buscan minimizar colisiones, estas pueden ocurrir, lo que puede ralentizar ligeramente las operaciones en el peor caso (afectando la constante en O(1)).
  • Orden: Hasta Python 3.7, el orden de los elementos en un diccionario dependía del orden de inserción y de los hashes de las claves. Desde Python 3.7 en adelante, los diccionarios mantienen el orden de inserción de las claves como un efecto secundario de la implementación, pero esto no forma parte del mecanismo de hashing.

Ejemplo de un objeto hashable y no hashable:

# Objeto hashable (inmutable)
string_key = "hello"
int_key = 123
tuple_key = (1, 2)

print(hash(string_key))
print(hash(int_key))
print(hash(tuple_key))

# Objeto no hashable (mutable)
list_key = [1, 2]
# print(hash(list_key)) # Esto generará un TypeError

# Ejemplo de uso en un diccionario
my_dict = {
    string_key: "world",
    int_key: 456,
    tuple_key: "una tupla"
}

print(my_dict[string_key])
print(my_dict[int_key])
print(my_dict[tuple_key])

Por lo tanto, el hash es un mecanismo fundamental que permite a los diccionarios en Python alcanzar un alto rendimiento en sus operaciones, basado en el cálculo rápido de la representación numérica de la clave.