Python进阶8——字典与散列表,字符串编解码

        Python用散列表来实现字典,散列表就是稀疏数组(数组中有空白元素),散列表中的元素叫做表元,字典的每个键值对都占用一个表元,一个表元分成两个部分,一个是对键的应用,另一个是对值的引用,因为表元的大小一致,所以可以通过稀疏数组(散列表)的偏移量读取指定的表元

        Python会保证散列表中三分之一的表元都是空的,当向字典中添加元素时,散列表就会用键值对填充表元,当达到剩余三分之一表元是空的时,会将当前的散列表放到一个更大的空间中

        当通过key获取字典的value时(求取dict[key]),过程如下:

        1.调用hash(key)求取key的散列值。

        2.把散列值的低几位当做偏移量,查找散列表里对应的表元。

        3.如果表元为空,抛出异常(keyerror),如果表元不为空,会找到一对foundkey:foundvalue。

        4.如果foundkey与key相等,返回foundvalue,如果foundkey与key不相等,发生散列冲突,执行第5步。

        5.算法在散列值中再取几位,通过新的散列值计算索引,再查找对应的表元,然后执行3和4。

        上述过程的流程图如下:

        添加元素和更新值的过程和上述流程基本一致,添加元素时,如果发现是空表元,会直接添加值,更新值时,找到对应的表元后,原表元里的值会被更新为新值。    

        散列冲突并不会总发生,所以字典的速度很快。

        因为字典通过key查找value是通过hash函数计算散列值,所以字典的key必须支持hash函数,且通过hash函数计算出的散列值是唯一的,所以key可以使用字符串(str),整型(int),元祖(tuple),但是不能是list

        因为散列表是稀疏的,所以字典所占内存极高,典型的空间换时间

        因为当向字典中添加键值对时,可能会发生散列冲突,导致键值对的出现在字典中的顺序不同,比如,添加一个key和value,如果没有发生散列冲突,那么该键值对出现在字典中的位置可能靠前,如果发生了散列冲突,就有可能出现在字典中靠后的位置,所以键值对在字典中的位置完全取决于添加顺序

举例

l=[(2,'two'), (1,'one'), (4,'four'), (3,'three')]
d1=dict(l);
print(d1.keys(), d1.items())
d2=dict(sorted(l));#按照key排序
print(d2.keys(),d2.items())
d3=dict(sorted(l, key =lambda x : x[1]))#按照value排序
print(d3.keys(),d3.items())
print(d1==d2==d3)

        可见,虽然Python都认为上述三个字典是相等的,但是键值对在字典中的顺序完全不同

        因为向字典中添加新的键值对时,有可能导致字典内部的散列表重新分配内存,当把字典中的元素重新添加到新的内存中时,可能导致散列冲突,从而导致键值对在字典中的位置发生变化

        这样在循环迭代并同时添加键值对时就有可能跳过一些键

        所以,在对已有字典进行循环迭代时,不要同时进行添加操作,而应该先新建一个空字典,将要添加的键值对放在空字典中,然后对原有字典和新字典进行合并

合并字典可用update方法

l1=[(2,'two'), (1,'one'), (4,'four'), (3,'three')]
l2=[(5,'five'), (6,'six'), (7,'seven'), (8,'eight')]
dl1=dict(l1)
dl2=dict(l2)
d=dict()
d.update(dl1)
d.update(dl2)
print(d)

         编码就是将文本字符串转化为字节序列,解码就是将字节序列转化为文本字符串,常见的编解码格式有utf8,字节序列计算机识别,文本字符串人类识别

举例

s1='helloworld'
t1=s1.encode('utf8')
print(t1)
s2=t1.decode('utf8')
print(s2)

 

参考

1.《流畅的Python》

2.  https://blog.csdn.net/jerry_1126/article/details/73017270

 

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值