python思考

廖雪峰学习python的官网上有这样一段话:

#前言

和list比较,dict有以下几个特点:

查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:

查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。

dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。

上面说字典要占用大量的内存,我就去查了一下python中字典的实现方式:

http://liuzhijun.iteye.com/blog/2266358

发现讲python字典实现的一篇好文章

python见闻志

总结一下,
dict{key:value}
key通过hash函数,得到一个数(十进制),跟存储数组的长度 - 1 进行&操作,得到slot索引。
如:hash(‘a’) = 398026104856367068
如果数组的大小是8
hash(‘a’) & 7 = 0;

hash.png

图片引用自:https://harveyqing.gitbooks.io/python-read-and-write/content/

如果索引重复,就是用开放寻址法来查找空闲的slot,所以会形成一个探测链,当探测链中某个元素被删除时,不能直接删除,否则探测链就断了,就不能根据探测链来查找删除元素后面的元素了。 删除时通多dummy状态来标志。有三种状态,unused,active,dummy

Q:像这种探测链确定位置的元素怎么查找到呢?

先根据hash值来查找,找到一个元素,比较key值,不一样,然后根据探测链往下查找,直到比较key值是一样的,就找到了。

如果使用了的slots和dummy slots的总量超过了数组大小的2/3则重新调整字典的大小,然后slot索引会重新计算一遍。