2. Sets

2.12. TypeError: unhashable


Un objeto es hashable si tiene un valor hash que nunca cambia durante su vida útil.

Un objeto hashable no puede cambiar: es Inmutable.

Los objetos que pueden cambiar o mutar se dice que son  NO Hashables.

El termino Hashable se asocia con Resumible, por que el Hash va a resumir el objeto y es resumible por que el Hash NUNCA cambia.


Algunos tipos de datos que pueden arrojar ese error son:

  • List (Listado): Admite cualquier tipo de valores
  • Dict (Diccionario): Admite solo claves Resumibles (Hashables) y valores de cualquier tipo
  • Set (Conjunto): Admite solo valores Resumibles (Hashables)


El error indicado como Typeerror: Unhashable type ocurre cuando tratamos de usar un tipo de dato que puede cambiar en un lugar donde debería ir un dato que NO puede cambiar (hashable).



Diccionario:

Recordemos que un diccionario tiene alguna restricción respecto de su clave:

  • NO PUEDE REPETIRSE.
  • NO SE PUEDE MODIFICAR
Si trato de asignar como clave de un diccionario algo inmutable un objeto que puede cambiar me tira error del tipo : TypeError: unhashable type



Si se descomentaran las líneas 7 , 8 y 9 veríamos errores del tipo:
Respectivamente, esto sucede por que la clave de un diccionario NO puede cambiar es: Hashable, pero lo que intentamos poner como clave puede cambiar.. por lo tanto tira el error.
Veamos que la línea que asigna una Tupla ( que es inmutable) como clave NO tira error.
La salida del scritp sería:

Set:

Recordemos que un diccionario tiene alguna restricción respecto de su clave:

  • NO PUEDE REPETIRSE.
  • NO SE PUEDE MODIFICAR
Veamos este scritp:

Al igual que el caso anterior, cuando intentamos agregar elementos que pueden cambiar (Diccionario o Lista) a un set que tiene que tener elementos NO se pueden cambiar tiraría error si descomentamos las líneas 7 y 8.
Esto no sucede cuando agregamos una tupla que es inmutable o el nro. 7 en la línea 5 que también es Inmutable.
La salida del Scritp sería:

Veamos otro caso, el de agregar un set a otro set.
Esto también tiraría un error por que set2 puede cambiar.. y los elementos de set1 NO pueden cambiar, si se puede agregar... pero sería otro objeto.

Objeto Hashable vs. Elementos de un objeto Hashable.

No confundir el concepto de que un elemento sea hashable, como la tupla , con las claves de un diccionario o con los elementos de un set.
Veamos el siguiente código:

La salida de este script será:
 
La salida None ocurre para todos menos para la tupla, que es inmutable!
El método __hash__ permite calcular un número inmutable de un objeto. Los que varían como Listas, Diccionarios y sets NO tiene Hash ( None).
Veamos algunos casos mas.

Podemos ver que los enteros, reales y string son Hashables, al igual que la tupla y la clave de un diccionario y los elementos de un set.
Lo mismo pasa para los Valores de Diccionarios y listas.
NO así para las Listas y Diccionarios.