HASH
Hash, 一般翻译做'散列', 也有直接音译为'哈希'的, 就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转化是一种压缩映射,也就是,散列值得空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
特征:
hash 的值是根据输入值的特征计算的,这就要求被hash的值必须固定, 因此被hash的值必须是不可变得
用途:
文件签名
MD5加密
密码加密
可变与不可变类型
可变类型
不可变类型
list
bool, int, float, complex
dict
str
set
tuple
frozenset
列表
>>> l = [1,2,3,4]
>>> id(l)
4392665160
>>> l[1] = 1.5
>>> l
[1, 1.5, 3, 4]
>>> id(l)
4392665160
数字
>>> a = 1
>>> id(a)
4297537952
>>> a+=1
>>> id(a)
4297537984
从内存角度看列表与数字的变与不变
字符串
#例1
>>> s = 'hello'
>>> s[1] = 'a'
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
s[1] = 'a'
TypeError: 'str' object does not support item assignment
#例2
>>> s = 'hello'
>>> id(s)
4392917064
>>> s += ' world'
>>> s
'hello world'
>>> id(s)
4393419504
#字符串也可以像列表一样使用索引操作,但是通过上例可以看出,我们不能像修改列表一样修改一个字符串的值,当我们对字符串进行拼接的时候,原理和整数一样,id值已经发生了变化,相当于变成了另外一个字符串。
元组——不允许修改
>>> t = (1,2,3,4)
>>> t[1] = 1.5
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
t[1] = 1.5
TypeError: 'tuple' object does not support item assignment
hash
假设现在要你存储一些数据如下,你会怎么存?
张三 13980593357
李四 15828662334
王老五 13409821234
[[‘张三’,13980593357][‘李四’,15828662334][‘王老五’,13409821234]]
像上面这样存行不行?
可以~现在咱们有一个需求,就是获取“王五”的电话号码,你怎么做?
遍历整个列表,找到“王五”的信息所在的列表,然后拿到王五的电话。看起来一切顺利。
但是当我们需要存储的人越来越多,这个寻找的过程就会变得非常漫长,如果我们存了5000万个人的信息,那么找人这个过程就变得像大海捞针一样了。。。有没有什么好办法能够让我们一下子就找到对应的人呢?
我们都知道数据是存储在内存里的,内存中的每一个位置都有自己的地址标示。假如我们能够将这些人名转换成数字直接存储在数字代表的内存地址中,等要找这个人的时候,直接去这个地址找人是不是就方便了?
假如对上述的联系人信息进行存储时,采用的Hash函数为:姓名的每个字的拼音开头大写字母的ASCII码之和。因此
address(张三)=ASCII(Z)+ASCII(S)=90+83=173;
address(李四)=ASCII(L)+ASCII(S)=76+83=159;
address(王老五)=ASCII(W)+ASCII(L)+ASCII(W)=87+76+87=250;
当然了,这只是一个示意图,具体的情况比这个还要复杂,还有很多复杂的因素都没有考虑进入,比如如果计算出来的hash值发生了冲突怎么办?还有现在这张图就可以看出空间上的浪费,这就需要我们在设计hash算法的时候不能像我刚刚假设的那样随意。但这已经足以向你说明hash算法的与众不同,它能为你在数据查找的过程中节省多少时间。
现在,告诉你一个好消息,你不需要关心hash值是如何计算的,因为python已经为我们设计了一套算法你只要拿来用就可以:
>>> hash("张三")
6480394008723176318
>>> hash("李四")
-114706925611844552
>>> hash("王老五")
3250319002057530081