截至Python 3.7,对内置dict 的新改进是:
dict 对象的插入顺序保存特性已被宣布为 Python 语言规范的官方部分。
这意味着不再需要OrderedDict ?。它们几乎相同。
需要考虑的一些小细节...
以下是 Python 3.7+ dict 和 OrderedDict 之间的一些比较:
from collections import OrderedDict
d = {'b': 1, 'a': 2}
od = OrderedDict([('b', 1), ('a', 2)])
# they are equal with content and order
assert d == od
assert list(d.items()) == list(od.items())
assert repr(dict(od)) == repr(d)
显然,这两个对象的字符串表示形式有所不同,dict 对象的形式更加自然和紧凑。
str(d) # {'b': 1, 'a': 2}
str(od) # OrderedDict([('b', 1), ('a', 2)])
至于两者方法不同,这个问题可以用集合论来回答:
d_set = set(dir(d))
od_set = set(dir(od))
od_set.difference(d_set)
# {'__dict__', '__reversed__', 'move_to_end'} for Python 3.7
# {'__dict__', 'move_to_end'} for Python 3.8+
这意味着OrderedDict 最多有两个dict 没有内置的功能,但这里显示了解决方法:
对于 Python 3.8+,which fixed this issue 确实不需要解决方法。 OrderedDict 可以“反转”,它只是反转键(不是整个字典):
reversed(od) # <odict_iterator at 0x7fc03f119888>
list(reversed(od)) # ['a', 'b']
# with Python 3.7:
reversed(d) # TypeError: 'dict' object is not reversible
list(reversed(list(d.keys()))) # ['a', 'b']
# with Python 3.8+:
reversed(d) # <dict_reversekeyiterator at 0x16caf9d2a90>
list(reversed(d)) # ['a', 'b']
使用 Python 3.7+ 正确反转整个字典:
dict(reversed(list(d.items()))) # {'a': 2, 'b': 1}
move_to_end 的解决方法
OrderedDict 有一个move_to_end 方法,实现起来很简单:
od.move_to_end('b') # now it is: OrderedDict([('a', 2), ('b', 1)])
d['b'] = d.pop('b') # now it is: {'a': 2, 'b': 1}