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

2020-12-30 15:47:34 浏览数 (1)

参考链接: Python使用散列的地址计算排序

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 人点赞