什么使列表不可用?

usu*_* me 7 python hash dictionary list python-internals

所以列表是不可用的:

>>> { [1,2]:3 }
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

以下页面给出了解释:

列表是可变类型,不能用作字典中的键(它可以就地更改,使得键不再可以在字典的内部哈希表中找到).

我理解为什么不可能将可变对象用作字典键.但是,即使我只是尝试哈希列表(独立于字典创建),Python也会引发相同的异常

>>> hash( [1,2] )
TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

Python这样做是为了保证可变类型永远不会被用作字典键吗?或者是否存在使可变对象无法散列的另一个原因,无论我打算如何使用它们?

the*_*eye 18

字典和集合使用散列算法来唯一地确定项目.并且这些算法利用用作密钥的项来获得唯一的哈希值.由于列表是可变的,因此列表的内容可以更改.允许列表作为键存在于字典中后,如果列表的内容发生更改,则哈希值也将更改.如果散列值在存储在字典中的特定插槽后发生更改,则会导致字典不一致.例如,最初列表将存储在位置A,该位置是基于散列值确定的.如果哈希值发生变化,并且如果我们查找列表,我们可能无法在位置找到它A,或者根据新的哈希值,我们可能会找到一些其他对象.

由于无法提出哈希值,因此内部没有为列表定义哈希函数.

PyObject_HashNotImplemented,                /* tp_hash */
Run Code Online (Sandbox Code Playgroud)

由于未实现散列函数,当您将其用作字典中的键,或强制尝试使用hash函数获取散列值时,它无法散列它,因此它以不可变类型失败

TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)