@@ -100,6 +100,21 @@ The class can be used to simulate nested scopes and is useful in templating.
100
100
:func: `super ` function. A reference to ``d.parents `` is equivalent to:
101
101
``ChainMap(*d.maps[1:]) ``.
102
102
103
+ Note, the iteration order of a :class: `ChainMap() ` is determined by
104
+ scanning the mappings last to first::
105
+
106
+ >>> baseline = {'music': 'bach', 'art': 'rembrandt'}
107
+ >>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
108
+ >>> list(ChainMap(adjustments, baseline))
109
+ ['music', 'art', 'opera']
110
+
111
+ This gives the same ordering as a series of :meth: `dict.update ` calls
112
+ starting with the last mapping::
113
+
114
+ >>> combined = baseline.copy()
115
+ >>> combined.update(adjustments)
116
+ >>> list(combined)
117
+ ['music', 'art', 'opera']
103
118
104
119
.. seealso ::
105
120
@@ -163,8 +178,8 @@ contexts::
163
178
e.maps[-1] # Root context -- like Python's globals()
164
179
e.parents # Enclosing context chain -- like Python's nonlocals
165
180
166
- d['x'] # Get first key in the chain of contexts
167
181
d['x'] = 1 # Set value in current context
182
+ d['x'] # Get first key in the chain of contexts
168
183
del d['x'] # Delete from current context
169
184
list(d) # All nested values
170
185
k in d # Check all nested values
@@ -253,15 +268,20 @@ For example::
253
268
254
269
.. versionadded :: 3.1
255
270
271
+ .. versionchanged :: 3.7 As a :class:`dict` subclass, :class:`Counter`
272
+ Inherited the capability to remember insertion order. Math operations
273
+ on *Counter * objects also preserve order. Results are ordered
274
+ according to when an element is first encountered in the left operand
275
+ and then by the order encountered in the right operand.
256
276
257
277
Counter objects support three methods beyond those available for all
258
278
dictionaries:
259
279
260
280
.. method :: elements()
261
281
262
282
Return an iterator over elements repeating each as many times as its
263
- count. Elements are returned in arbitrary order. If an element's count
264
- is less than one, :meth: `elements ` will ignore it.
283
+ count. Elements are returned in the order first encountered. If an
284
+ element's count is less than one, :meth: `elements ` will ignore it.
265
285
266
286
>>> c = Counter(a = 4 , b = 2 , c = 0 , d = - 2 )
267
287
>>> sorted (c.elements())
@@ -272,10 +292,10 @@ For example::
272
292
Return a list of the *n * most common elements and their counts from the
273
293
most common to the least. If *n * is omitted or ``None ``,
274
294
:meth: `most_common ` returns *all * elements in the counter.
275
- Elements with equal counts are ordered arbitrarily :
295
+ Elements with equal counts are ordered in the order first encountered :
276
296
277
- >>> Counter(' abracadabra' ).most_common(3 ) # doctest: +SKIP
278
- [('a', 5), ('r ', 2), ('b ', 2)]
297
+ >>> Counter(' abracadabra' ).most_common(3 )
298
+ [('a', 5), ('b ', 2), ('r ', 2)]
279
299
280
300
.. method :: subtract([iterable-or-mapping])
281
301
@@ -887,7 +907,7 @@ field names, the method and attribute names start with an underscore.
887
907
888
908
.. method :: somenamedtuple._asdict()
889
909
890
- Return a new :class: `OrderedDict ` which maps field names to their corresponding
910
+ Return a new :class: `dict ` which maps field names to their corresponding
891
911
values:
892
912
893
913
.. doctest ::
@@ -1024,17 +1044,41 @@ customize a prototype instance:
1024
1044
:class: `OrderedDict ` objects
1025
1045
----------------------------
1026
1046
1027
- Ordered dictionaries are just like regular dictionaries but they remember the
1028
- order that items were inserted. When iterating over an ordered dictionary,
1029
- the items are returned in the order their keys were first added.
1047
+ Ordered dictionaries are just like regular dictionaries but have some extra
1048
+ capabilities relating to ordering operations. They have become less
1049
+ important now that the built-in :class: `dict ` class gained the ability
1050
+ to remember insertion order (this new behavior became guaranteed in
1051
+ Python 3.7).
1052
+
1053
+ Some differences from :class: `dict ` still remain:
1054
+
1055
+ * The regular :class: `dict ` was designed to be very good at mapping
1056
+ operations. Tracking insertion order was secondary.
1057
+
1058
+ * The :class: `OrderedDict ` was designed to be good at reordering operations.
1059
+ Space efficiency, iteration speed, and the performance of update
1060
+ operations were secondary.
1061
+
1062
+ * Algorithmically, :class: `OrderedDict ` can handle frequent reordering
1063
+ operations better than :class: `dict `. This makes it suitable for tracking
1064
+ recent accesses (for example in an `LRU cache
1065
+ <https://medium.com/@krishankantsinghal/my-first-blog-on-medium-583159139237> `_).
1066
+
1067
+ * The equality operation for :class: `OrderedDict ` checks for matching order.
1068
+
1069
+ * The :meth: `popitem ` method of :class: `OrderedDict ` has a different
1070
+ signature. It accepts an optional argument to specify which item is popped.
1071
+
1072
+ * :class: `OrderedDict ` has a :meth: `move_to_end ` method to
1073
+ efficiently reposition an element to an endpoint.
1074
+
1075
+ * Until Python 3.8, :class: `dict ` lacked a :meth: `__reversed__ ` method.
1076
+
1030
1077
1031
1078
.. class :: OrderedDict([items])
1032
1079
1033
- Return an instance of a dict subclass, supporting the usual :class: `dict `
1034
- methods. An *OrderedDict * is a dict that remembers the order that keys
1035
- were first inserted. If a new entry overwrites an existing entry, the
1036
- original insertion position is left unchanged. Deleting an entry and
1037
- reinserting it will move it to the end.
1080
+ Return an instance of a :class: `dict ` subclass that has methods
1081
+ specialized for rearranging dictionary order.
1038
1082
1039
1083
.. versionadded :: 3.1
1040
1084
@@ -1084,29 +1128,7 @@ anywhere a regular dictionary is used.
1084
1128
:class: `OrderedDict ` Examples and Recipes
1085
1129
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1086
1130
1087
- Since an ordered dictionary remembers its insertion order, it can be used
1088
- in conjunction with sorting to make a sorted dictionary::
1089
-
1090
- >>> # regular unsorted dictionary
1091
- >>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
1092
-
1093
- >>> # dictionary sorted by key
1094
- >>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
1095
- OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
1096
-
1097
- >>> # dictionary sorted by value
1098
- >>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
1099
- OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
1100
-
1101
- >>> # dictionary sorted by length of the key string
1102
- >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
1103
- OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
1104
-
1105
- The new sorted dictionaries maintain their sort order when entries
1106
- are deleted. But when new keys are added, the keys are appended
1107
- to the end and the sort is not maintained.
1108
-
1109
- It is also straight-forward to create an ordered dictionary variant
1131
+ It is straightforward to create an ordered dictionary variant
1110
1132
that remembers the order the keys were *last * inserted.
1111
1133
If a new entry overwrites an existing entry, the
1112
1134
original insertion position is changed and moved to the end::
@@ -1115,21 +1137,29 @@ original insertion position is changed and moved to the end::
1115
1137
'Store items in the order the keys were last added'
1116
1138
1117
1139
def __setitem__(self, key, value):
1118
- if key in self:
1119
- del self[key]
1120
- OrderedDict.__setitem__(self, key, value)
1140
+ super().__setitem__(key, value)
1141
+ super().move_to_end(key)
1121
1142
1122
- An ordered dictionary can be combined with the :class: ` Counter ` class
1123
- so that the counter remembers the order elements are first encountered ::
1143
+ An :class: ` OrderedDict ` would also be useful for implementing
1144
+ variants of :func: ` functools.lru_cache ` ::
1124
1145
1125
- class OrderedCounter(Counter, OrderedDict):
1126
- 'Counter that remembers the order elements are first encountered '
1146
+ class LRU( OrderedDict):
1147
+ 'Limit size, evicting the least recently looked-up key when full '
1127
1148
1128
- def __repr__(self):
1129
- return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
1149
+ def __init__(self, maxsize=128, *args, **kwds):
1150
+ self.maxsize = maxsize
1151
+ super().__init__(*args, **kwds)
1130
1152
1131
- def __reduce__(self):
1132
- return self.__class__, (OrderedDict(self),)
1153
+ def __getitem__(self, key):
1154
+ value = super().__getitem__(key)
1155
+ self.move_to_end(key)
1156
+ return value
1157
+
1158
+ def __setitem__(self, key, value):
1159
+ super().__setitem__(key, value)
1160
+ if len(self) > self.maxsize:
1161
+ oldest = next(iter(self))
1162
+ del self[oldest]
1133
1163
1134
1164
1135
1165
:class: `UserDict ` objects
0 commit comments