Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是;“可散列”;用Python是什么意思?_Python - Fatal编程技术网

什么是;“可散列”;用Python是什么意思?

什么是;“可散列”;用Python是什么意思?,python,Python,我试着在网上搜索,但找不到hashable的含义 当他们说对象是可散列的或可散列的对象是什么意思?来自: 如果一个对象的哈希值在其生存期内从不改变(它需要一个\uuuuu hash\uuuu()方法),并且可以与其他对象进行比较(它需要一个\uuuu eq\uuuu()或\uu cmp\uuuuu()方法),则该对象是可哈希的。比较相等的可散列对象必须具有相同的散列值 哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值 Python的所有不可变内置对象都是可散列的,而没有可变容

我试着在网上搜索,但找不到hashable的含义

当他们说对象是可散列的或可散列的对象是什么意思?

来自:

如果一个对象的哈希值在其生存期内从不改变(它需要一个
\uuuuu hash\uuuu()
方法),并且可以与其他对象进行比较(它需要一个
\uuuu eq\uuuu()
\uu cmp\uuuuu()
方法),则该对象是可哈希的。比较相等的可散列对象必须具有相同的散列值

哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值

Python的所有不可变内置对象都是可散列的,而没有可变容器(如列表或字典)是可散列的。默认情况下,作为用户定义类实例的对象是可散列的;它们都比较不相等,它们的散列值是它们的
id()


在python中,这意味着对象可以是集合的成员,以便返回索引。也就是说,它们具有唯一的标识/id

例如,在python 3.3中:


数据结构列表不可散列,但数据结构元组可散列

让我给你一个工作示例来理解python中的可哈希对象。我拿两个元组作为例子。元组中的每个值都有一个唯一的哈希值,在其生命周期内不会改变。基于这个has值,我们对两个元组进行了比较。我们可以使用Id()获取元组元素的哈希值


根据Python术语表的理解,当您创建可散列对象的实例时,也会根据实例的成员或值计算不可更改的值。 例如,该值可以用作字典中的键,如下所示:

>>> tuple_a = (1, 2, 3)
>>> tuple_a.__hash__()
2528502973977326415
>>> tuple_b = (2, 3, 4)
>>> tuple_b.__hash__()
3789705017596477050
>>> tuple_c = (1, 2, 3)
>>> tuple_c.__hash__()
2528502973977326415
>>> id(a) == id(c)  # a and c same object?
False
>>> a.__hash__() == c.__hash__()  # a and c same value?
True
>>> dict_a = {}
>>> dict_a[tuple_a] = 'hiahia'
>>> dict_a[tuple_c]
'hiahia'
我们可以发现
tuple_a
tuple_c
的散列值是相同的,因为它们具有相同的成员。 当我们使用
tuple\u a
作为
dict\u a
中的键时,我们可以发现
dict\u a[tuple\u c]
的值是相同的,这意味着当它们被用作字典中的键时,它们返回相同的值,因为散列值是相同的。 对于那些不可散列的对象,方法
\uuuu hash\uuu
被定义为
None

>>> type(dict.__hash__) 
<class 'NoneType'>
>>>类型(dict.\uuuu散列)

我猜这个散列值是在实例初始化时计算的,不是以动态方式计算的,这就是为什么只有不可变的对象才可以散列。希望这能有所帮助。

这里的所有答案都对python中的可哈希对象进行了很好的解释,但我认为首先需要理解术语哈希

散列是计算机科学中的一个概念,用于创建高性能、伪随机访问数据结构,以便快速存储和访问大量数据

例如,如果您有10000个电话号码,并且希望将其存储在阵列中(这是一种顺序数据结构,将数据存储在连续的内存位置,并提供随机访问),但您可能没有所需数量的连续内存位置

因此,您可以使用大小为100的数组,并使用哈希函数将一组值映射到相同的索引,这些值可以存储在链接列表中。这提供了类似于阵列的性能

现在,哈希函数可以简单地将数字除以数组的大小,并将余数作为索引

有关更多详细信息,请参阅


这里还有一个很好的参考:

任何不可变的东西(可变的意思,可能会改变)都可以散列。除了要查找的散列函数之外,如果类有它,通过例如
dir(tuple)
和查找
\uuuuuuuuuuuuuuuuu
方法,下面是一些示例

#x = hash(set([1,2])) #set unhashable
x = hash(frozenset([1,2])) #hashable
#x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
x = hash((1,2,3)) #tuple of immutable objects, hashable
#x = hash()
#x = hash({1,2}) #list of mutable objects, unhashable
#x = hash([1,2,3]) #list of immutable objects, unhashable
不可变类型列表:

int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
list, dict, set, bytearray, user-defined classes
可变类型列表:

int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
list, dict, set, bytearray, user-defined classes

为了从头开始创建哈希表,所有值都必须设置为“None”,并在需求出现时进行修改。
散列对象是指可修改的数据类型(字典、列表等)。另一方面,集合一旦分配就不能重新初始化,因此集合是不可散列的。然而,set()的变量--frozenset()--是可散列的。

hashable=可以散列

好的,什么是散列?哈希函数是一个函数,它接受一个对象,比如一个字符串,比如“Python”,并返回一个固定大小的代码。为简单起见,假设返回值为整数

在Python3中运行hash('Python')时,得到的结果是5952713340227947791。不同版本的Python可以自由更改底层哈希函数,因此您可能会得到不同的值。重要的是,无论我现在多次运行hash('Python'),我都会使用相同版本的Python得到相同的结果

但是hash('Java')返回1753925553814008565。因此,如果我正在散列的对象发生变化,结果也会发生变化。另一方面,如果我正在散列的对象没有改变,那么结果保持不变

为什么这很重要

例如,Python字典要求键是不可变的。也就是说,关键点必须是不变的对象。字符串在Python中是不可变的,其他基本类型(int、float、bool)也是不可变的。元组和冻结集也是不可变的。另一方面,列表不是一成不变的(即,它们是可变的),因为您可以更改它们。类似地,dict是可变的

所以当我们说某些东西是可散列的,我们的意思是它是不可变的。如果我尝试将可变类型传递给hash()函数,它将失败:

>>> hash('Python')
1687380313081734297
>>> hash('Java')
1753925553814008565
>>>
>>> hash([1, 2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash({1, 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> hash({1 : 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>>
>>> hash(frozenset({1, 2}))
-1834016341293975159
>>> hash((1, 2))
3713081631934410656
>>散列('Python')
1687380313081734297
>>>散列('Java')
1753925553814008565
>>>
>>>散列([1,2])
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
>>>散列({1,2})
回溯(最近一次呼叫最后一次):
菲尔