在使用Python的字典时,我们发现,当输出字典的内容时,输出内容的顺序和我们建立字典时候添加内容的输入顺序不一致。其
实,我们使用的是Python默认的字典,这种字典是不按顺序存储、输出我们添加在字典中的内容的。要想输出内容的顺序和我们建
立字典时候添加内容的输入顺序一致,就要用到有序字典。
一、
defaultdict
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
注意默认值是调用函数返回的,而函数在创建defaultdict
对象时传入。
除了在Key不存在时返回默认值,defaultdict
的其他行为跟dict
是完全一样的。
OrderedDict
使用dict
时,Key是无序的。在对dict
做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']
OrderedDict
可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key:
from collections import OrderedDict
class LastUpdatedOrderedDict(OrderedDict):
def __init__(self, capacity):
super(LastUpdatedOrderedDict, self).__init__()
self._capacity = capacity
def __setitem__(self, key, value):
containsKey = 1 if key in self else 0
if len(self) - containsKey >= self._capacity:
last = self.popitem(last=False)
print 'remove:', last
if containsKey:
del self[key]
print 'set:', (key, value)
else:
print 'add:', (key, value)
OrderedDict.__setitem__(self, key, value)
二、
Ordered dictionaries are just like regular dictionaries but they remember the order that items were inserted. When iterating over an ordered dictionary, the items are returned in the order their keys were first added.
-
class
-
Return an instance of a dict subclass, supporting the usual
dict
methods. An OrderedDict is a dict that remembers the order that keys were first inserted. If a new entry overwrites an existing entry, the original insertion position is left unchanged. Deleting an entry and reinserting it will move it to the end.New in version 3.1.
-
The
popitem()
method for ordered dictionaries returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.
popitem
( last=True )-
Move an existing key to either end of an ordered dictionary. The item is moved to the right end if last is true (the default) or to the beginning if last is false. Raises
KeyError
if the key does not exist:New in version 3.2.
move_to_end
( key, last=True ) -
collections.
OrderedDict
(
[
items
]
)
In addition to the usual mapping methods, ordered dictionaries also support reverse iteration using reversed()
.
Equality tests between OrderedDict
objects are order-sensitive and are implemented as list(od1.items())==list(od2.items())
. Equality tests between OrderedDict
objects and other Mapping
objects are order-insensitive like regular dictionaries. This allows OrderedDict
objects to be substituted anywhere a regular dictionary is used.
The OrderedDict
constructor and update()
method both accept keyword arguments, but their order is lost because Python’s function call semantics pass in keyword arguments using a regular unordered dictionary.
8.3.6.1. OrderedDict
Examples and Recipes
Since an ordered dictionary remembers its insertion order, it can be used in conjunction with sorting to make a sorted dictionary:
The new sorted dictionaries maintain their sort order when entries are deleted. But when new keys are added, the keys are appended to the end and the sort is not maintained.
It is also straight-forward to create an ordered dictionary variant that remembers the order the keys were last inserted. If a new entry overwrites an existing entry, the original insertion position is changed and moved to the end:
An ordered dictionary can be combined with the Counter
class so that the counter remembers the order elements are first encountered:
注:
有序字典OrderedDict是Python的内建模块collections的一个函数,使用时可以用“from collections import OrderedDict”导入使用
https://docs.python.org/3.4/library/collections.html#module-collections