很多人认为python中的字典是无序的,因为它是按照hash来存储的,但是python中有个模块collections(英文,收集、集合),里面自带了一个子类OrderedDict,实现了对字典对象中元素的排序。
在Python 3.5(含)以前,字典是不能保证顺序的,键值对A先插入字典,键值对B后插入字典,但是当你打印字典的Keys列表时,你会发现B可能在A的前面。 但是从Python 3.6开始,字典是变成有顺序的了。你先插入键值对A,后插入键值对B,那么当你打印Keys列表的时候,你就会发现B在A的后面。 不仅如此,从Python 3.6开始,下面的三种遍历操作,效率要高于Python 3.5之前。
d = dict() d['a'] = 'A' d['m'] = 'm' d['b'] = 'B' d['1'] = 2 d['c'] = 'C' d['d'] = 'D' d['e'] = 'E' d['2'] = 3 print(d)
{'a': 'A', 'm': 'm', 'b': 'B', '1': 2, 'c': 'C', 'd': 'D', 'e': 'E', '2': 3}
import collections d1 = collections.OrderedDict() d1['a'] = 'A' d1['b'] = 'B' d1['c'] = 'C' d1['1'] = '1' d1['2'] = '2' print(d1)
OrderedDict([('a', 'A'), ('b', 'B'), ('c', 'C'), ('1', '1'), ('2', '2')])
可以看到,同样是保存了ABC等几个元素,但是使用OrderedDict会根据放入元素的先后顺序进行排序。所以输出的值是排好序的。
OrderedDict对象的字典对象,如果其顺序不同那么Python也会把他们当做是两个不同的对象,请看事例:
print('Regular dictionary:') d2 = dict() d2['a'] = 'A' d2['b'] = 'B' d2['c'] = 'C' d3 = dict() d3['c'] = 'C' d3['a'] = 'A' d3['b'] = 'B' print(d2 == d3) print('OrderedDict:') d4 = collections.OrderedDict() d4['a'] = 'A' d4['b'] = 'B' d4['c'] = 'C' d5 = collections.OrderedDict() d5['c'] = 'C' d5['a'] = 'A' d5['b'] = 'B' print(d4 == d5)
Regular dictionary: True OrderedDict: False
dd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2} # 按key排序 kd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[0])) print(kd) # 按照value排序 vd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[1])) print(vd)
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
有序词典就像常规词典一样,但有一些与排序操作相关的额外功能。由于内置的 dict 类获得了记住插入顺序的能力(在 Python 3.6之后保证了这种新行为),它们变得不那么重要了。
OrderedDict 与 dict 的 Key 会按照插入的顺序排列,不是 Key 本身排序
一些与 dict 的不同仍然存在:
常规的 dict 被设计为非常擅长映射操作。 跟踪插入顺序是次要的。
OrderedDict 旨在擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的。
算法上, OrderedDict 可以比 dict 更好地处理频繁的重新排序操作。 这使其适用于跟踪最近的访问(例如在 LRU cache 中)。
对于 OrderedDict ,相等操作检查匹配顺序。
OrderedDict 类的 popitem() 方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。
OrderedDict 类有一个 move_to_end() 方法,可以有效地将元素移动到任一端。
Python 3.8之前, dict 缺少 reversed() 方法。
class collections.OrderedDict([items]):返回一个 dict 子类的实例,它具有专门用于重新排列字典顺序的方法。