Lista imprimible, pero hashable tupla?

¿ En cómo hash listas? Me dijeron que primero debería convertir a una tupla, por ejemplo, [1,2,3,4,5] a (1,2,3,4,5) .

Así que el primero no puede ser hecho un hash, pero el segundo puede. ¿Por qué * ?


* Realmente no estoy buscando una explicación técnica detallada, sino una intuición.

Principalmente, porque las tuplas son inmutables. Supongamos los siguientes trabajos:

 >>> l = [1, 2, 3] >>> t = (1, 2, 3) >>> x = {l: 'a list', t: 'a tuple'} 

Ahora, ¿qué pasa cuando haces l.append(4) ? ¡Has modificado la clave en tu diccionario! ¡Desde lejos! Si está familiarizado con cómo funcionan los algoritmos de hash, esto debería asustarlo. Las tuplas, por otro lado, son absolutamente inmutables. t += (1,) puede parecer que está modificando la tupla, pero en realidad no lo es: simplemente está creando una nueva tupla, sin cambiar la clave del diccionario.

Podrías hacer que funcione, pero apuesto a que no te gustarían los efectos.

 from functools import reduce from operator import xor class List(list): def __hash__(self): return reduce(xor, self) 

Ahora veamos que pasa:

 >>> l = List([23,42,99]) >>> hash(l) 94 >>> d = {l: "Hello"} >>> d[l] 'Hello' >>> l.append(7) >>> d {[23, 42, 99, 7]: 'Hello'} >>> l [23, 42, 99, 7] >>> d[l] Traceback (most recent call last): File "", line 1, in  KeyError: [23, 42, 99, 7] 

Edición: Así que pensé en esto un poco más. Podría hacer que el ejemplo anterior funcione, si devuelve el ID de la lista como su valor hash:

 class List(list): def __hash__(self): return id(self) 

En ese caso, d[l] te dará 'Hello' , pero ni d[[23,42,99,7]] ni d[List([23,42,99,7])] (porque tú re creando una nueva [Ll]ist .

Dado que una lista es mutable, si la modificas también modificarías su hash, lo que arruina el punto de tener un hash (como en un conjunto o una clave de dictado).

Porque las listas son mutables y las tuplas no lo son.

Las respuestas son buenas. La razón es la mutabilidad. Si pudiéramos usar listar en dicts como claves; (o cualquier objeto mutable) entonces podríamos cambiar la clave al mutar esa clave (accidental o intencionalmente). Esto causaría un cambio en el valor de hash de la clave en el diccionario debido a lo cual no podríamos rastrear el valor de esa estructura de datos por esa clave. Los valores de hash y las tablas de hash se utilizan para mapear los datos grandes con facilidad asignándolos a índices que almacenan las entradas de valor real.

Lee más sobre ellos aquí:-

Hash Tables & Hash Functions & Assosiative Arrays

No todas las tuplas son hashables. Por ejemplo, la tupla contiene la lista como un elemento.

 x = (1,[2,3]) print(type(x)) print(hash(x))