如何保持键值对与声明顺序一致?

403 投票
13 回答
428634 浏览
提问于 2025-04-15 16:48

我有一个字典,我是按照特定的顺序声明的,想要它一直保持这个顺序。字典里的键和值不能根据它们的值来排序,我只是想保持我声明时的顺序。

比如我有这个字典:

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

但是当我查看或者遍历它的时候,顺序并不是我想要的那样。有没有什么办法可以确保Python会保持我声明的键和值的顺序呢?

13 个回答

177

与其讲解理论部分,我给大家一个简单的例子。

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}
182
from collections import OrderedDict
OrderedDict((word, True) for word in words)

包含

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

如果这些值是 True(或者其他任何不可改变的对象),你也可以使用:

OrderedDict.fromkeys(words, True)
380

从Python 3.6开始,标准的dict类型默认会保持插入的顺序。

定义

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

会生成一个字典,字典中的键会按照源代码中列出的顺序排列。

这个功能是通过使用一个简单的整数数组来实现的,这个数组用于稀疏哈希表,其中的整数用来索引另一个存储键值对(以及计算出的哈希值)的数组。这个后面的数组正好是按照插入的顺序来存储这些项目,而整个组合实际上比Python 3.5及之前的实现占用更少的内存。想了解更多细节,可以查看Raymond Hettinger的原始想法帖子

在3.6版本中,这仍然被视为一种实现细节;可以参考Python 3.6的新特性文档

这个新实现保持顺序的特性被认为是实现细节,不应该被依赖(未来可能会改变,但希望在语言中保留这个新的字典实现几个版本,然后再修改语言规范,以强制所有当前和未来的Python实现都保持顺序;这也有助于与旧版本的语言保持向后兼容,因为在旧版本中,迭代顺序是随机的,比如Python 3.5)。

Python 3.7将这个实现细节提升为语言规范,因此现在所有与该版本或更新版本兼容的Python实现都必须保证dict保持顺序。可以查看BDFL的声明。从Python 3.8开始,字典还支持反向迭代

在某些情况下,你可能仍然想使用collections.OrderedDict(),因为它在标准dict类型的基础上提供了一些额外的功能。例如,它是可逆的(这也扩展到视图对象),并且支持重新排序(通过move_to_end()方法)。

撰写回答