首页 > 解决方案 > 什么决定了 Python 3.6 中字典的顺序

问题描述

我正在使用数据框字典对 NFL 球队进行一些分析。我需要遍历字典(向后,按插入时间排序)以进行我计划进行的分析。每个 NFL 球队都有自己的字典。代码和输出截图

我的函数使用类似于顶部显示的行的代码遍历字典。每个键都是一个元组,元组中的第二个条目表示比赛进行的(NFL 赛季)周。我最初插入第 1 周的键和值,然后插入第 2 周的键和值,然后插入第 3 周的键和值。看到输出,这按计划工作,这意味着我的功能应该按预期工作。实践中没有问题。但是,如果您查看字典本身,则键是乱序的(请参阅第二个输出)。

那么查看字典时,究竟是什么决定了键的顺序呢?Buccaneers 的字典是 2 -> 1 -> 3。但每个球队的字典都不是这样。顺序似乎完全随机。是什么决定了这个顺序?我很好奇(我肯定将它们按 1 -> 2 -> 3 的顺序插入每个团队)。我正在使用 Python 3.6

标签: pythondictionarypython-3.6

解决方案


有关详细信息,请参阅此问题总而言之,字典从CPython 3.6开始按插入顺序排序,但这是Python 3.7 规范之前的实现细节。该文档指出:

在 3.7 版更改: 字典顺序保证为插入顺序。

因此,您的问题的答案是:

  • 如果您特别指的是CPython,则字典顺序就是插入顺序(尽管规范不保证这一点,理论上可以想象 CPython 3.6 的补丁会破坏这种行为)
  • 如果您指的是任何实现(CPython、Jython、PyPy ...),则该实现确定字典顺序:不保证顺序(除非实现指定)。

你可能会问,为什么字典的实现不是按插入顺序排列的。我建议你检查哈希表数据结构。基本上,值被放入一个数组中,具体取决于键的哈希值。哈希是一个将键映射到数组单元格索引的函数。这就是查找速度如此之快的原因:获取键,计算哈希,读取单元格中的值(我忽略了冲突解决细节),而不是扫描整个(键,值)对列表。

不能保证散列键的顺序与键的插入顺序(或键本身的顺序)相同。如果通过扫描数组来列出键,键的顺序似乎是随机的。


备注:您可以使用OrderDict该类强制对键进行排序,但这是键的顺序(例如'Opponent' < 'Reference')。


推荐阅读