【问题标题】:What makes lists unhashable?是什么让列表不可散列?
【发布时间】:2014-04-24 12:28:32
【问题描述】:

所以列表是不可散列的:

>>> { [1,2]:3 }
TypeError: unhashable type: 'list'

下面page给出解释:

列表是可变类型,不能用作字典中的键 (它可能会就地更改,使密钥不再位于 字典的内部哈希表)。

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

>>> hash( [1,2] )
TypeError: unhashable type: 'list'

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

【问题讨论】:

  • hash() 只是调用对象的__hash__ 方法,而这正是dicts 所做的。
  • 您打算对哈希做什么?动机是一个对象的哈希值不应该改变,相等的对象通常应该是相同的。

标签: python list dictionary hash python-internals


【解决方案1】:

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

由于无法得出哈希值,内部有no hashing function defined for lists

PyObject_HashNotImplemented,                /* tp_hash */

由于没有实现散列函数,当你将它作为字典中的键使用时,或者用hash函数强行尝试获取散列值时,它无法散列它,因此它以不可散列类型失败

TypeError: unhashable type: 'list'

【讨论】:

    猜你喜欢
    • 2012-05-02
    • 2020-03-30
    • 2016-09-05
    • 2023-01-14
    • 1970-01-01
    • 2012-01-30
    • 2017-01-24
    相关资源
    最近更新 更多