在python中,dict和list是两种常见数据类型,dict用于内容空间足够、根据值快速检索的场景,list用于内存空间有限、根据下标快速检索的场景。
使用场景:
List:类似于C中的array数组,数据存储在一段连续内存空间中;根据值查询时候,需要从头到尾逐一遍历,复杂度O(N),但根据索引index查询时候,直接做索引index偏移,复杂度O(1)。
Dict:在python底层实现为可变哈希表,本质也可以看做List,区别在于List只存放数值,而Dict存放数值所对应的索引+数值。
原理说明:
List:python底层实现为一个长度可变的数组,数组中存放的是每个元素的索引inference,根据索引查询不受List长度和所存放的元素影响。对于频繁的append和insert操作,CPython会额外进行一些技巧,比如频繁append时候会额外分配比实际需要大一些的空间,避免频繁开辟空间。
Dict:可变哈希表,key通过hash函数映射为哈希值,哈希值进一步映射到哈希表大小size的位置index上,value的地址就存放在index所对应的空间上。说明:Dict中的key必须是可哈希(python中不可变数据都是可哈希的,而可变数据则不可哈希),原因是一旦key可变,key发生变化之后,则无法根据变化后的新key值查询到value,也可以查询到旧key值对应的value值。
注意点:
1、使用List,根据value检索会是O(N)时间复杂度,建议下标index检索。
2、使用Dict,根据key检索value虽然会很快,但会占用更多空间,因为哈希表会至少空出1/3的空间,insert操作会在哈希表大小达到2/3触发扩容操作。
3、底层数据存放时候,List是按操作先后顺序存放,而Dict会按照key的哈希值存放,实际value会无序存放。
常见问题(个人理解,欢迎大神指出错误):
1、当初始化一个非空dict时,python底层进行了哪些过程?
答:
step1:开辟一段连续的内存空间用于哈希表操作。
step2:计算各个key的哈希值,再根据哈希值计算value在哈希表中的存放位置,中间可能会遇到哈希冲突和哈希表扩容。
step3:为value开辟内容空间,将具体值存放进去。
step4:将value值所在内存空间的地址存放到哈希表的相应位置空间上。
step5:将哈希表所在内存空间的地址存放到字段变量所在的空间上。
2、为什么说Dict的元素是无序存放?
答:key的哈希计算无序,哈希冲突导致无序,哈希表扩容重新哈希导致无序。
3、dict进行insert时候,如何解决哈希冲突?
答:
4、dict在扩容时候,如何解决扩容操作?
5、什么是哈希表?
6、数据存放在list或者dict中时候,实际数据是如何存放的?
7、为什么dict的key需要不可变?
来源:CSDN
作者:qm006
链接:https://blog.csdn.net/qm5132/article/details/104108523