NPE*_*NPE 154
一个目的是可哈希如果它有一个哈希值其寿命(它需要一个在这期间从不改变
__hash__()方法),并且可相对于其他对象(它需要一个__eq__()或__cmp__()方法).比较相等的可哈希对象必须具有相同的哈希值.Hashability使对象可用作字典键和set成员,因为这些数据结构在内部使用哈希值.
所有Python的不可变内置对象都是可清除的,而没有可变容器(例如列表或字典).默认情况下,作为用户定义类实例的对象是可清除的; 他们都比较不平等,他们的哈希值是他们的
id().
小智 84
这里的所有答案都对python中的hashable对象有很好的解释,但我相信首先需要理解Hashing这个术语.
哈希是计算机科学中的一个概念,用于创建高性能的伪随机访问数据结构,其中大量数据将被快速存储和访问.
例如,如果您有10,000个电话号码,并且您希望将它们存储在一个阵列中(这是一个将数据存储在连续内存位置并提供随机访问的顺序数据结构),但您可能没有所需的连续数量记忆位置.
因此,您可以使用大小为100的数组,并使用散列函数将一组值映射到相同的索引,并且这些值可以存储在链接列表中.这提供了类似于阵列的性能.
现在,哈希函数可以像将数字除以数组的大小并将余数作为索引一样简单.
有关更多详细信息,请参阅https://en.wikipedia.org/wiki/Hash_function
这是另一个很好的参考:http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html
use*_*754 12
任何不可变的东西(可变的意思,可能会改变)都可以进行哈希处理.除了要查找的哈希函数,如果一个类有它,例如.dir(tuple)并寻找__hash__方法,这里有一些例子
#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
Run Code Online (Sandbox Code Playgroud)
不可变类型列表:
int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
Run Code Online (Sandbox Code Playgroud)
可变类型列表:
list, dict, set, bytearray, user-defined classes
Run Code Online (Sandbox Code Playgroud)
Sid*_*qui 12
Hashable = 能够被散列。
好的,什么是哈希?散列函数是一个函数,它接受一个对象,比如一个字符串,比如“Python”,并返回一个固定大小的代码。为简单起见,假设返回值是一个整数。
当我在 Python 3 中运行 hash('Python') 时,我得到 5952713340227947791 作为结果。不同版本的 Python 可以自由更改底层哈希函数,因此您可能会得到不同的值。重要的是,无论现在我运行 hash('Python') 多少次,使用相同版本的 Python 总是得到相同的结果。
但是 hash('Java') 返回 1753925553814008565。所以如果我正在散列的对象发生变化,结果也会发生变化。另一方面,如果我正在散列的对象没有改变,那么结果保持不变。
为什么这很重要?
嗯,例如,Python 字典要求键是不可变的。也就是说,键必须是不会改变的对象。字符串在 Python 中是不可变的,其他基本类型(int、float、bool)也是如此。元组和冻结集也是不可变的。另一方面,列表不是一成不变的(即它们是可变的),因为您可以更改它们。同样,dicts 是可变的。
所以当我们说某些东西是可散列的时,我们的意思是它是不可变的。如果我尝试将可变类型传递给 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
Run Code Online (Sandbox Code Playgroud)
小智 9
在 Python 中,任何不可变对象(例如整数、布尔值、字符串、元组)都是可散列的,这意味着其值在其生命周期内不会改变。这允许 Python 创建一个唯一的哈希值来识别它,字典可以使用它来跟踪唯一键和集合来跟踪唯一值。
这就是 Python 要求我们为字典中的键使用不可变数据类型的原因。
小智 6
根据Python术语表的理解,当您创建可清除对象的实例时,还会根据实例的成员或值计算不可更改的值.例如,该值可以用作dict中的键,如下所示:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
我们可以发现tuple_a和tuple_c的哈希值是相同的,因为它们具有相同的成员.当我们使用tuple_a作为dict_a中的键时,我们可以发现dict_a [tuple_c]的值是相同的,这意味着当它们被用作dict中的键时,它们返回相同的值,因为哈希值是相同.对于那些不可清除的对象,方法哈希定义为None:
>>> type(dict.__hash__)
<class 'NoneType'>
Run Code Online (Sandbox Code Playgroud)
我想这个哈希值是在实例初始化时计算的,而不是以动态方式计算的,这就是为什么只有不可变对象是可以清除的.希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
110342 次 |
| 最近记录: |