¿Por qué no puedo usar una lista como clave de dictado en Python? ¿Exactamente qué se puede y qué no se puede utilizar y por qué?

Resuelto wim asked hace 13 años • 11 respuestas

Descubrí que todos los siguientes son válidos:

>>> d = {}
>>> d[None] = 'foo'
>>> d[(1, 3)] = 'baz'

Incluso un módulo se puede utilizar como clave de dictado:

>>> import sys
>>> d[sys] = 'bar'

Sin embargo, una lista no puede, y tampoco una tupla que contiene una lista:

>>> d[[2]] = 'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> d[(1, [3])] = 'qux'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

¿Por qué almacenar una lista dentro de la tupla significa que ya no puede ser una clave de dictado? Después de todo, podría fácilmente "ocultar" una lista dentro de un módulo (y de hecho, por ejemplo, ya sys.pathes una lista).

Tenía una vaga idea de que la clave tiene que ser "hashable", pero no tengo una comprensión detallada de lo que esto significa o de por qué existe tal limitación. ¿Qué saldría mal si Python permitiera usar listas como claves, por ejemplo, usar su ubicación de memoria como hash?

wim avatar Aug 31 '11 20:08 wim
Aceptado

Hay un buen artículo sobre el tema en la wiki de Python: Por qué las listas no pueden ser claves de diccionario . Como se explica allí:

¿Qué saldría mal si Python permitiera usar listas como claves, por ejemplo, usar su ubicación de memoria como hash?

Causaría algún comportamiento inesperado. Las listas generalmente se tratan como si su valor se derivara de los valores de su contenido, por ejemplo al verificar la (des)igualdad. Muchos esperarían, comprensiblemente, que pueda usar cualquier lista [1, 2]para obtener la misma clave, donde tendría que mantener exactamente el mismo objeto de lista. Pero la búsqueda por valor se interrumpe tan pronto como se modifica una lista utilizada como clave, y la búsqueda por identidad requiere realizar un seguimiento de ese objeto de lista exacto, lo cual no es un requisito común para trabajar con listas.

Otros objetos, como los módulos y object, le dan mucha más importancia a su identidad de objeto (¿cuándo fue la última vez que tuviste dos objetos de módulo distintos llamados sys?), y de todos modos se comparan mediante eso. Por lo tanto, es menos sorprendente, o incluso esperado, que, cuando se usan como claves de dictado, también se comparen por identidad en ese caso.

 avatar Aug 31 '2011 13:08

¿Por qué no puedo usar una lista como clave de dictado en Python?

>>> d = {repr([1,2,3]): 'value'}
{'[1, 2, 3]': 'value'}

Como explicaron otros aquí, de hecho no se puede. Sin embargo, puedes usar su representación de cadena si realmente quieres usar tu lista.

Remi avatar Aug 31 '2011 13:08 Remi

Una lista se puede convertir en una tupla, que se puede utilizar como clave de dictado: por ejemplo

d = {tuple([1,2,3]): 'value'}
Ningrong Ye avatar Aug 02 '2018 18:08 Ningrong Ye

El problema es que las tuplas son inmutables y las listas no. Considere este ejemplo:

d = {}
li = [1,2,3]
d[li] = 5
li.append(4)

¿ Qué debería d[li]regresar? ¿Es la misma lista? Qué tal si d[[1,2,3]]? Tiene los mismos valores, pero ¿es una lista diferente?

En definitiva, no hay una respuesta satisfactoria:

  • Si la única clave que funciona es la clave original, entonces resulta imposible acceder al valor sin conservar una referencia a la clave original (y tener acceso a ella)

  • Si solo funciona una clave con el mismo contenido, modificar la clave cambia el funcionamiento de la búsqueda; y cualquier otro código que tenga referencia a esa lista podría modificarla, posiblemente provocando una sorpresa más adelante.

  • Si ambos funcionan, entonces tendrá claves muy diferentes asignadas al mismo valor, lo cual es más que sorprendente.

Eric Wilson avatar Aug 31 '2011 13:08 Eric Wilson

Aquí hay una respuesta http://wiki.python.org/moin/DictionaryKeys

¿Qué saldría mal si intentaras usar listas como claves, con el hash como, por ejemplo, su ubicación de memoria?

Buscar diferentes listas con el mismo contenido produciría resultados diferentes, aunque comparar listas con el mismo contenido las indicaría como equivalentes.

¿Qué pasa con el uso de una lista literal en una búsqueda en un diccionario?

bpgergo avatar Aug 31 '2011 13:08 bpgergo