Python(1)

Python 的Dict和List

要理解dict的有关内容需要理解哈希表(map)的相关基础知识,这个其实是《算法与数据结构》里面的内容。

list和tuple是用链表顺序存储的:前一个元素存储了下一个元素的位置;
list的名字就是一个指针,指向list的第一个元素的位置;
假设一个链表总共就2个元素,如何在第一个元素和第二个元素中间插入第三个元素?直接在这个链表的最后面,也就是第三个元素的位置插入这个元素,然后让第一个元素指向这个元素(也就是第三个位置),让后让新插入的元素指向原来的第二个元素就完成了。
读取这个list的时候,先用list的名字(就是个指针,指向第1个元素的位置)找到第一个元素,然后用第1一个元素的指针找到第2个元素(位置3),然后用第2个元素的指针找到第3个元素(位置2),以此类推。所以list的顺序和内存中的实际顺序其实不一定完全对应。这种存储方式不会浪费内存,但查找起来特别费时间,因为要按照链表一个一个找下去,如果list特别大的话,那么要等好久才会找到结果。

2.dict是用哈希表的方式实现快速查找。哈希表采用哈希函数从key计算得到一个数字(哈希函数有个特点:对于不同的key,有很大的概率得到的哈希值也不同),然后直接把value存储到这个数字所对应的地址上,比如key=‘ABC’,value=10,经过哈希函数得到key对应的哈希值为123,那么就申请一个有1000个地址(从0到999)的内存,然后把10存放在地址为123的地方。类似的,对于key=‘BCD’,value=20,得到key的哈希值为234,那么就把20存放在地址为234的地方。对于这样的表查找起来是非常方便的。只要给出key,计算得到哈希值,然后直接到对应的地址去找value就可以了。无论有几个元素,都可以直接找到value,无需遍历整个表。不过虽然dict查找速度快,但内存浪费严重,你看我们只存储了两个元素,都要申请一个长度为1000的内存。

和list比较,dict有以下几个特点:
查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。

3.有上述可见dict的key必须使用不可变对象。
因为不可变对象是常量,每次的哈希值算出来都是固定的,这样就不会出错。比如key=‘ABC’,value=10,存储地址为123,假设我突发奇想,把key改成’BCD’,那么当查找’BCD’的value的时候就会去234的地址找,但那里啥也没有,这就乱套了。
在Python中可变的数据类型主要包括:List,Set,Dictionary
虽然Dict是可变的数据类型,但是Dict里面的key又是不可变的数据类型。
不可变的数据类型主要包括:Number(int,float,bool,complex),String,Tuple

3.你看我们上面有一句话:对于不同的key,有很大的概率得到的哈希值也不同。那么有很小的概率不同的key可以得到相同的哈希值了?没错,比如对于我们的例子来说,哈希值只有3位,那么只要元素个数超过1000,就一定会有至少两个key的哈希值相同(鸽笼原理),这种情况叫“冲突”,设计哈希表的时候要采取办法减少冲突,实在冲突了也要想办法补救。不过这是编译器的事情,况且对于初学者的我们来说碰到的冲突的概率基本等于零,就不用操心了。

4.需要牢记:dict内部存放的顺序和key放入的顺序是没有关系的。

5.对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
比如说,a=‘abc’ 'abc’是字符串,是不可变对象,但是a是变量,是可变的,a指向的内容才是不可变的对象。如果:
a.replace(‘a’,‘A’)
输出结果是‘Abc’,但是a的输出结果仍然是‘abc’。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值