@@ -887,7 +887,7 @@ field names, the method and attribute names start with an underscore.
887887
888888.. method :: somenamedtuple._asdict()
889889
890- Return a new :class: `OrderedDict ` which maps field names to their corresponding
890+ Return a new :class: `dict ` which maps field names to their corresponding
891891 values:
892892
893893 .. doctest ::
@@ -1024,17 +1024,41 @@ customize a prototype instance:
10241024:class: `OrderedDict ` objects
10251025----------------------------
10261026
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.
1027+ Ordered dictionaries are just like regular dictionaries but have some extra
1028+ capabilities relating to ordering operations. They have become less
1029+ important now that the built-in :class: `dict ` class gained the ability
1030+ to remember insertion order (this new behavior became guaranteed in
1031+ Python 3.7).
1032+
1033+ Some differences from :class: `dict ` still remain:
1034+
1035+ * The regular :class: `dict ` was designed to be very good at mapping
1036+ operations. Tracking insertion order was secondary.
1037+
1038+ * The :class: `OrderedDict ` was designed to be good at reordering operations.
1039+ Space efficiency, iteration speed, and the performance of update
1040+ operations were secondary.
1041+
1042+ * Algorithmically, :class: `OrderedDict ` can handle frequent reordering
1043+ operations better than :class: `dict `. This makes it suitable for tracking
1044+ recent accesses (for example in an `LRU cache
1045+ <https://medium.com/@krishankantsinghal/my-first-blog-on-medium-583159139237> `_).
1046+
1047+ * The equality operation for :class: `OrderedDict ` checks for matching order.
1048+
1049+ * The :meth: `popitem ` method of :class: `OrderedDict ` has a different
1050+ signature. It accepts an optional argument to specify which item is popped.
1051+
1052+ * :class: `OrderedDict ` has a :meth: `move_to_end ` method to
1053+ efficiently reposition an element to an endpoint.
1054+
1055+ * Until Python 3.8, :class: `dict ` lacked a :meth: `__reversed__ ` method.
1056+
10301057
10311058.. class :: OrderedDict([items])
10321059
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.
1060+ Return an instance of a :class: `dict ` subclass that has methods
1061+ specialized for rearranging dictionary order.
10381062
10391063 .. versionadded :: 3.1
10401064
@@ -1084,29 +1108,7 @@ anywhere a regular dictionary is used.
10841108:class: `OrderedDict ` Examples and Recipes
10851109^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10861110
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
1111+ It is straightforward to create an ordered dictionary variant
11101112that remembers the order the keys were *last * inserted.
11111113If a new entry overwrites an existing entry, the
11121114original insertion position is changed and moved to the end::
@@ -1115,21 +1117,29 @@ original insertion position is changed and moved to the end::
11151117 'Store items in the order the keys were last added'
11161118
11171119 def __setitem__(self, key, value):
1118- if key in self:
1119- del self[key]
1120- OrderedDict.__setitem__(self, key, value)
1120+ super().__setitem__(key, value)
1121+ super().move_to_end(key)
11211122
1122- An ordered dictionary can be combined with the :class: ` Counter ` class
1123- so that the counter remembers the order elements are first encountered ::
1123+ An :class: ` OrderedDict ` would also be useful for implementing
1124+ variants of :func: ` functools.lru_cache ` ::
11241125
1125- class OrderedCounter(Counter, OrderedDict):
1126- 'Counter that remembers the order elements are first encountered '
1126+ class LRU( OrderedDict):
1127+ 'Limit size, evicting the least recently looked-up key when full '
11271128
1128- def __repr__(self):
1129- return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
1129+ def __init__(self, maxsize=128, *args, **kwds):
1130+ self.maxsize = maxsize
1131+ super().__init__(*args, **kwds)
11301132
1131- def __reduce__(self):
1132- return self.__class__, (OrderedDict(self),)
1133+ def __getitem__(self, key):
1134+ value = super().__getitem__(key)
1135+ self.move_to_end(key)
1136+ return value
1137+
1138+ def __setitem__(self, key, value):
1139+ super().__setitem__(key, value)
1140+ if len(self) > self.maxsize:
1141+ oldest = next(iter(self))
1142+ del self[oldest]
11331143
11341144
11351145:class: `UserDict ` objects
0 commit comments