Python让字典保持有序

问题

我们想创建一个字典,同时当对字典做迭代或序列化操作时,也能控制其中元素的顺序。

解决方案

要控制字典中元素顺序,可以使用collections模块中的OrderedDict类。当对字典做迭代时,它会严格按照元素初始添加的顺序进行。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from collections import OrderedDict
print('Regular dictionary:')
d = {}
d['A'] = 1
d['B'] = 2
d['C'] = 3
d['D'] = 4
for k, v in d.items():
print(k, v)
print('OrderedDict:')
d = OrderedDict()
d['A'] = 1
d['B'] = 2
d['C'] = 3
d['D'] = 4
for k, v in d.items():
print(k, v)

输出结果,其中正常创建的字典,迭代时顺序是不确定的,但是用OrderedDict创建的字典迭代时会严格按照元素初始添加的顺序进行:

1
2
3
4
5
6
7
8
9
10
Regular dictionary:
A 1
B 2
D 4
C 3
OrderedDict:
A 1
B 2
C 3
D 4

当想构建一个映射结构以便稍后对其做序列化或编码成另一种格式时,OrderedDict就显得特别有用。例如,想对json编码时精确控制各字段的顺序,那么只要先在OrderedDict中构建数据就可以了:

1
2
3
4
>>> import json
>>> json.dumps(d)
{"A": 1, "B": 2, "C": 3, "D": 4}
>>>

讨论

OrderedDict内部维护了一个双向链表,它会根据元素加入的顺序来排列键的位置。第一个新添加的元素放置在链表的末尾。接下来对已存在的键做重新赋值时不会改变键的顺序。
请注意OrderedDict的大小是普通字典的2倍多,这是由于它额外创建的链表所致。因此,如果打算构建一个涉及大量OrderedDict字典的数据结构(例如从CSV文件中读取100000行内容到OrderedDict中),那么需要认真对应用做需求分析,从而使用OrderedDict所带来的好处是否能超越因额外的内存开销所带来的缺点。

大师兄 wechat
欢迎关注我的微信公众号:Python大师兄