Python3.6字典中按插入顺序进行遍历有序是为什么
Admin 2022-06-21 群英技术资讯 806 次浏览
这篇文章给大家分享的是Python3.6字典中按插入顺序进行遍历有序是为什么。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。字典的本质就是 hash 表,hash 表就是通过 key 找到其 value ,平均情况下你只需要花费 O(1) 的时间复杂度即可以完成对一个元素的查找,字典是否有序,并不是指字典能否按照键或者值进行排序,而是字典能否按照插入键值的顺序输出对应的键值。
比如,对于一个无序字典,插入顺序和遍历的顺序是不一致的:
>>> my_dict = dict() >>> my_dict["name"] = "lowman" >>> my_dict["age"] = 26 >>> my_dict["girl"] = "Tailand" >>> my_dict["money"] = 80 >>> my_dict["hourse"] = None >>> for key,value in my_dict.items(): ... print(key,value) ... money 80 girl Tailand age 26 hourse None name lowman
而一个有序字典的输出是这样的:
name lowman age 26 girl Tailand money 80 hourse None
那为什么 Python3.6 之后,Python 的字典就有序了呢?
先从 Python3.6 之前说起。在 Python 3.6 之前,其数据结构如下图所示:

由于不同键的哈希值不一样,哈希表(entries)中的顺序是按照哈希值大小排序的,遍历时从前往后遍历并不能输出键值插入的顺序,其表现起来就是无序的。
此外,这种方式还有一个缺点,就是如果以稀疏的哈希表存储时,会浪费较多的内存空间,Python3.6 之后,对其进行了优化,哈希索引和真正的键值对分开存放,数据结构如下所示:

indices 指向了一列索引,entries 指向了原本的存储哈希表内容的结构。
你可以把 indices 理解成新的简化版的哈希表,entries 理解成一个数组,数组中的每个元素是原本应该存储的哈希结果:键和值。
查找或者插入一个元素的时候,根据键的哈希值结果取模 indices 的长度,就能得到对应的数组下标,再根据对应的数组下标到 entries 中获取到对应的结果,比如 hash("key2") % 8 的结果是 3,那么 indices[3] 的值是 1,这时候到 entries 中找到对应的 entries[1] 既为所求的结果:

这么做的好处是空间利用率得到了较大的提升,我们以 64 位操作系统为例,每个指针的长度为 8 字节,则原本需要 8 * 3 * 8 为 192
现在变成了 8 * 3 * 3 + 1 * 8 为 80,节省了 58% 左右的内存空间,如下图所示:

此外,由于 entries 是按照插入顺序进行插入的数组,对字典进行遍历时能按照插入顺序进行遍历,这也是为什么 Python3.6 以后的版本字典对象是有序的原因。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
for循环用于迭代序列(即列表、元组、字典、集合或字符串)。for 语句的写法如从对象开始按顺序给变量赋值,元素个数重复这个过程。对象可以是列表(数组)、元组、字符串等。本文将详细讲解Python中for定义迭代方法详解,需要的可以了解一下
flask是python web开发的常用框架之一。本文将讲述flask如何实现修改密码和免密登录功能
这篇文章主要介绍了python 如何用terminal输入参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
我们平时在用python写一些脚本作为工具时,经常需要在其他脚本中加载该工具,这篇文章主要给大家介绍了关于Python中添加搜索路径的相关资料,需要的朋友可以参考下
最近在看Python基础教程(第三版),是之前python课的课本,但是之前没读过,虽然python一直用得挺多,但重新读读收获还挺大。这里做个笔记。先是迭代器是什么并简单实现一个迭代器,然后是实现了一些range()。迭代器是像循环一样重复很多次,但不会像列表那样一次性全部生成,而是需要用...
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008