是什么使列表不可哈希?
所以列表是不可哈希的:
>>> { [1,2]:3 }
TypeError: unhashable type: 'list'
下面这个 页面 给出了一个解释:
列表是一种可变类型,不能用作字典的键(因为它可能会在原地改变,这样键就无法在字典的内部哈希表中找到)。
我明白为什么不希望使用可变对象作为字典的键。不过,Python在我尝试对一个列表进行哈希处理时也会抛出同样的异常(这和创建字典无关)。
>>> hash( [1,2] )
TypeError: unhashable type: 'list'
Python这样做是为了确保可变类型永远不能作为字典的键吗?还是说有其他原因导致可变对象无法被哈希,无论我打算怎么使用它们?
1 个回答
18
字典和集合使用一种叫做哈希算法的东西来唯一地识别一个项目。这些算法会利用作为键的项目来生成一个独特的哈希值。由于列表是可变的,也就是说它的内容可以改变,所以如果你把一个列表作为字典的键,之后这个列表的内容发生了变化,那么它的哈希值也会跟着改变。如果哈希值在存储后发生变化,字典就会变得不一致。举个例子,最开始这个列表可能被存储在位置A,这个位置是根据哈希值决定的。如果哈希值改变了,当我们去查找这个列表时,可能在位置A
找不到它,或者根据新的哈希值,我们可能会找到其他的东西。
因为无法为列表生成哈希值,所以内部并没有为列表定义哈希函数。
PyObject_HashNotImplemented, /* tp_hash */
由于没有实现哈希函数,当你把列表用作字典的键,或者强行用hash
函数来获取哈希值时,它会失败,并提示类型不可哈希。
TypeError: unhashable type: 'list'