可散列和不可变之间有什么区别?

时间:2019-05-15 17:25:35

标签: python immutability hashable

  • 不可变和可散列的有什么区别?
  • 这是什么意思“如果对象的哈希值在其生命周期内从未发生变化,则该对象是可哈希的?”
  • 元组是不可变且可哈希的还是仅不可变的?为什么?

3 个答案:

答案 0 :(得分:3)

哈希是某些哈希算法对大量数据的应用;通常以一种将其压缩为更小的值的方式在哈希查找表中进行搜索。哈希的一些示例包括MD5SHA-2

某些散列在产生冲突时被视为“失效”,这意味着两个截然不同的数据导致相同的“压缩”字符串或整数。因为存在冲突,所以MD5已失效,但是大多数SHA-2变体都没有。

不可变性是确保某些事物不变的过程。例如,想象一下C程序的静态二进制文件。将其发布到万维网或最终用户后,您不希望其内容发生更改,因此希望它是不可变的。

这与哈希相关。一旦“哈希”了一个对象,就不要更改其内容,否则将导致获得不同的哈希。如果您更改内容并且哈希值未更改,那么您将发生冲突!

元组只是一个数据结构,应该是不可变的和可哈希的。如果您在执行此操作时遇到麻烦,则可能是代码问题。

答案 1 :(得分:3)

  1. 不可变表示无法更改对象(该项目的顶级容器)。请注意,这仅适用于 顶层;它可能包含对可变子对象的引用。

  2. 可哈希具有函数定义:Python的内置hash函数返回一个值。通常,这意味着对象的闭包(所有对其叶子节点值的引用之后)都由不可变的对象组成。

  3. 您的前提不正确:元组可以包含可变项。任何此类引用都会使元组不可哈希。

例如:

>>> b = [7]
>>> a = (b, 5)
>>> a
([7], 5)
>>> type(a)
<class 'tuple'>
>>> set(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> b[0] = 'b'
>>> a
(['b'], 5)

b是一个可变列表。对b引用可以保存在元组a中。我们可以更改b[0]的值(不是它是对象句柄),并且a的显示值也会更改。但是,我们不能创建一个包含a的集合,因为b的可变性使a变得无法散列。

继续示例:

>>> b = False
>>> a
(['b'], 5)
>>> b = [14]
>>> a
(['b'], 5)

a是不可变的。因此,当我们更改b时,只有b获得对新对象的引用。 a保留原始对象句柄,仍指向['b']

答案 2 :(得分:2)

  1. 可哈希表示可以对对象进行哈希处理(与hash()函数一起使用时会产生一个值,而不可变表示对象不能被“突变”或更改。它们倾向于一起可变)参数将是可怕的字典键(它们每次更改时都将更改其哈希值)
  2. 如果某项的值与hash(item)相关联,则该值是可哈希的
  3. 组是不可变且可哈希的