为什么Python 3.7以后的字典是有序的_了解解释器底层实现对序列化的影响

浅枫大大_2193

浅枫大大_2193

2026-05-03

957人浏览

原创

python 3.7+ 字典有序是语言规范强制要求,非cpython特有;其底层采用indices+entries双数组紧凑结构,确保插入顺序遍历与o(1)查找兼顾;json.dumps()默认忠实输出该顺序,无需ordereddict。

为什么python 3.7以后的字典是有序的_了解解释器底层实现对序列化的影响

Python 3.7+ 的字典是有序的,这不是巧合,也不是优化副产品,而是语言规范强制要求的行为——你可以在任何合规实现(CPython、PyPy、Jython)中安全依赖插入顺序。

Python 3.7 字典有序是语言规范,不是 CPython 特性

很多人误以为“3.6 就有序了,所以 3.7 没啥变化”,这是危险的认知。Python 3.6 中字典看似有序,但官方文档明确标注为“CPython 实现细节,不应依赖”。这意味着:

  • PyPy 或 Jython 在 3.6 下可能返回乱序
  • json.dumps({'b': 2, 'a': 1}) 在 3.6 环境下跨平台可能输出 {"b": 2, "a": 1} 或 {"a": 1, "b": 2}
  • 3.6 的有序性不适用于 **kwargs 解包或类 __annotations__ 遍历等场景

而 Python 3.7 起,PEP 558 正式将“dict 保持插入顺序”写入语言规范。所有符合标准的解释器都必须实现该行为。

紧凑字典结构:indices + entries 双数组设计

有序性的底层支撑是“紧凑字典”(compact dict)结构,它拆分为两个物理数组:

  • indices:稀疏索引数组,每个元素是 int8,只存 entry 在 entries 中的下标,或 -1 表示空位
  • entries:紧凑条目数组,按插入顺序连续存储 [hash, key, value] 三元组

插入 d['x'] = 1 时流程是:

  • 计算 'x' 的 hash 值
  • 用 hash 映射到 indices 某个槽位(比如索引 3)
  • 把新 entry 追加到 entries 末尾,记下它的下标(比如是第 0 个)
  • 把 indices[3] 设为 0

遍历时只需顺序扫描 entries,天然有序;查找时仍靠 indices 快速跳转,不牺牲 O(1) 平均性能。

提示词大师-python版
提示词大师-python版

图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍

下载

JSON 序列化依赖字典迭代顺序,3.7+ 才真正可靠

json.dumps() 不自己排序,它直接按 dict.__iter__() 返回的顺序序列化。因此字典是否有序,直接决定 JSON 输出是否可预测:

  • 在 Python 3.7+ 中:json.dumps({'c': 3, 'a': 1, 'b': 2}) 总是输出 {"c": 3, "a": 1, "b": 2}
  • 如果你手动构造配置字典并期望前端按特定顺序渲染字段,这个顺序就是插入顺序
  • 使用 json.dump() 写入文件后,diff 工具能稳定比对字段变更,前提是环境 ≥3.7

注意:sort_keys=True 会覆盖插入顺序,但那是显式干预;默认行为就是忠实反映 entries 数组顺序。

别把 OrderedDict 当默认解药,普通 dict 在 3.7+ 已足够

很多人看到“有序”第一反应是 import OrderedDict,这反而可能引入问题:

  • OrderedDict 是独立类型,isinstance(d, dict) 为 False,某些框架(如 FastAPI 的 Pydantic v1)会拒绝它
  • 它额外维护双向链表,内存占用比普通 dict 高约 30%
  • 在 3.7+ 中,dict 和 OrderedDict 的顺序行为一致,但后者不兼容 **kwargs 解包的语义(例如 f(**od) 在某些旧版本会失败)

除非你需要 move_to_end() 或精确的相等判断(OrderedDict(a=1,b=2) == OrderedDict(b=2,a=1) 为 False),否则直接用 dict 更轻量、更标准。

真正容易被忽略的是:有序性只保证“插入顺序”,不保证“修改顺序”。对已存在 key 赋值(如 d['x'] = 99)不会改变其在 entries 中的位置,也不会触发重排——这点和 OrderedDict.move_to_end() 有本质区别。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1611

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

3844

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1609

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

22157

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2727

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2767

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1103

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2143

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程