Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.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_Hash - Fatal编程技术网

哈希在python中做什么?

哈希在python中做什么?,python,hash,Python,Hash,我看到了一个代码示例,其中hash函数应用于元组。因此,它返回一个负整数。我想知道这个函数做什么?谷歌没有帮助。我发现一个页面解释了如何计算哈希,但它没有解释我们为什么需要这个函数。Python状态: 散列值是整数。它们用于在字典查找过程中快速比较字典键 Python字典实现为哈希表。因此,每当您使用字典时,hash() 此外,国家: 不可散列的值,即包含列表、字典或其他可变类型(通过值而不是对象标识进行比较)的值,不能用作键 字典和集合使用散列来快速查找对象。维基百科的文章是一个很好的起点。。

我看到了一个代码示例,其中
hash
函数应用于元组。因此,它返回一个负整数。我想知道这个函数做什么?谷歌没有帮助。我发现一个页面解释了如何计算哈希,但它没有解释我们为什么需要这个函数。

Python状态:

散列值是整数。它们用于在字典查找过程中快速比较字典键

Python字典实现为哈希表。因此,每当您使用字典时,
hash()

此外,国家:

不可散列的值,即包含列表、字典或其他可变类型(通过值而不是对象标识进行比较)的值,不能用作键


字典和集合使用散列来快速查找对象。维基百科的文章是一个很好的起点。

。每个值都需要有自己的散列,因此对于相同的值,即使它不是相同的对象,也会得到相同的散列

>>> hash("Look at me!")
4343814758193556824
>>> f = "Look at me!"
>>> hash(f)
4343814758193556824
散列值的创建方式需要确保生成的值均匀分布,以减少散列冲突的数量。哈希冲突是指两个不同的值具有相同的哈希。因此,相对较小的更改通常会导致非常不同的哈希

>>> hash("Look at me!!")
6941904779894686356
这些数字非常有用,因为它们可以在大量值集合中快速查找值。它们的两个使用示例是Python的
set
dict
。在
列表中
,如果要检查列表中是否有值,请使用
如果x在值中:
,Python需要遍历整个列表,并将
x
与列表中的每个值进行比较
。对于长
列表
,这可能需要很长时间。在
集合中,Python跟踪每个散列,当您在值中键入
if x:
时,Python将获得
x
的散列值,在内部结构中查找该值,然后仅将
x
与与
x
具有相同散列的值进行比较

字典查找也使用相同的方法。这使得在
set
dict
中的查找速度非常快,而在
列表中的查找速度很慢。这还意味着您可以在
列表
中拥有非散列对象,但不能在
集合
中拥有,也不能作为
dict
中的键。非散列对象的典型示例是任何可变的对象,这意味着您可以更改其值。如果您有一个可变对象,那么它不应该是可散列的,因为它的散列将在其生命周期内发生变化,这将导致很多混乱,因为一个对象可能会在字典中以错误的散列值结束

请注意,对于一次Python运行,值的哈希值只需要相同。在Python 3.3中,每运行一次Python,它们实际上都会发生变化:

$ /opt/python33/bin/python3
Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foo")
1849024199686380661
>>> 
$ /opt/python33/bin/python3
Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foo")
-7416743951976404299
这使得猜测某个字符串的哈希值变得更加困难,这是web应用程序等的一个重要安全特性

因此,哈希值不应永久存储。如果您需要永久性地使用散列值,您可以查看更“严重”的散列类型,这些类型可用于生成文件的可验证校验和等。

TL;博士: 请参阅:
hash()
用作比较对象的快捷方式,如果可以将对象与其他对象进行比较,则认为该对象是可哈希的。这就是为什么我们使用
hash()
。它还用于访问实现为的
dict
set
元素

技术考虑
  • 通常比较对象(可能涉及多个级别的递归)是昂贵的
  • 优选地,
    hash()
    函数的成本较低一个数量级(或几个数量级)
  • 比较两个哈希比比较两个对象容易,这就是快捷方式所在
如果您阅读过,他们使用哈希表,这意味着从对象派生键是在
O(1)
的字典中检索对象的基石。但是,这取决于哈希函数是否具有抗冲突能力。字典中的单词实际上是
O(n)

注意,可变对象通常是不可散列的。hashable属性意味着您可以将对象用作键。如果哈希值用作键,并且同一对象的内容发生更改,那么哈希函数应该返回什么?是同一把钥匙还是另一把钥匙?它取决于如何定义哈希函数

以身作则: 想象一下我们有这样一门课:

>>> class Person(object):
...     def __init__(self, name, ssn, address):
...         self.name = name
...         self.ssn = ssn
...         self.address = address
...     def __hash__(self):
...         return hash(self.ssn)
...     def __eq__(self, other):
...         return self.ssn == other.ssn
... 
请注意:这一切都是基于这样一个假设,即SSN对于个人来说永远不会更改(甚至不知道从权威来源实际验证该事实的位置)

我们有鲍勃:

>>> bob = Person('bob', '1111-222-333', None)
鲍勃去见一位法官,要求他改名:

>>> jim = Person('jim bo', '1111-222-333', 'sf bay area')
这就是我们所知道的:

>>> bob == jim
True
但这是两个分配了不同内存的不同对象,就像同一个人的两个不同记录一样:

>>> bob is jim
False
现在是hash()很方便的部分:

>>> dmv_appointments = {}
>>> dmv_appointments[bob] = 'tomorrow'
猜猜看:

>>> dmv_appointments[jim] #?
'tomorrow'
您可以从两个不同的记录访问相同的信息。 现在试试这个:

>>> dmv_appointments[hash(jim)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in __eq__
AttributeError: 'int' object has no attribute 'ssn'
>>> hash(jim) == hash(hash(jim))
True

在最后一个示例中,我展示了即使发生冲突,也会执行比较,对象不再相等,这意味着它成功地引发了一个
KeyError

您可以在python中使用
字典
数据类型。它非常类似于散列,它还支持嵌套,类似于to嵌套散列

例如:

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School" # Add new entry

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

有关更多信息,请参考此链接。

您是否查看了“转到此链接”(官方文档)。它规定了一切。去!我喜欢这个问题不是重复“它是什么”,而是“我们为什么需要它”。关于潜在的哈希冲突,官方链接非常令人困惑:
hash(-1)==hash(-2)
(
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School" # Add new entry

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])