bpo-36059: Update OrderedDict() docs to reflect that regular dicts ar… · python/cpython@3006059

@@ -887,7 +887,7 @@ field names, the method and attribute names start with an underscore.

887887888888

.. method:: somenamedtuple._asdict()

889889890-

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:

892892893893

.. doctest::

@@ -1017,17 +1017,41 @@ customize a prototype instance:

10171017

:class:`OrderedDict` objects

10181018

----------------------------

101910191020-

Ordered dictionaries are just like regular dictionaries but they remember the

1021-

order that items were inserted. When iterating over an ordered dictionary,

1022-

the items are returned in the order their keys were first added.

1020+

Ordered dictionaries are just like regular dictionaries but have some extra

1021+

capabilities relating to ordering operations. They have become less

1022+

important now that the built-in :class:`dict` class gained the ability

1023+

to remember insertion order (this new behavior became guaranteed in

1024+

Python 3.7).

1025+1026+

Some differences from :class:`dict` still remain:

1027+1028+

* The regular :class:`dict` was designed to be very good at mapping

1029+

operations. Tracking insertion order was secondary.

1030+1031+

* The :class:`OrderedDict` was designed to be good at reordering operations.

1032+

Space efficiency, iteration speed, and the performance of update

1033+

operations were secondary.

1034+1035+

* Algorithmically, :class:`OrderedDict` can handle frequent reordering

1036+

operations better than :class:`dict`. This makes it suitable for tracking

1037+

recent accesses (for example in an `LRU cache

1038+

<https://medium.com/@krishankantsinghal/my-first-blog-on-medium-583159139237>`_).

1039+1040+

* The equality operation for :class:`OrderedDict` checks for matching order.

1041+1042+

* The :meth:`popitem` method of :class:`OrderedDict` has a different

1043+

signature. It accepts an optional argument to specify which item is popped.

1044+1045+

* :class:`OrderedDict` has a :meth:`move_to_end` method to

1046+

efficiently reposition an element to an endpoint.

1047+1048+

* Until Python 3.8, :class:`dict` lacked a :meth:`__reversed__` method.

1049+1023105010241051

.. class:: OrderedDict([items])

102510521026-

Return an instance of a dict subclass, supporting the usual :class:`dict`

1027-

methods. An *OrderedDict* is a dict that remembers the order that keys

1028-

were first inserted. If a new entry overwrites an existing entry, the

1029-

original insertion position is left unchanged. Deleting an entry and

1030-

reinserting it will move it to the end.

1053+

Return an instance of a :class:`dict` subclass that has methods

1054+

specialized for rearranging dictionary order.

1031105510321056

.. versionadded:: 3.1

10331057

@@ -1077,29 +1101,7 @@ anywhere a regular dictionary is used.

10771101

:class:`OrderedDict` Examples and Recipes

10781102

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

107911031080-

Since an ordered dictionary remembers its insertion order, it can be used

1081-

in conjunction with sorting to make a sorted dictionary::

1082-1083-

>>> # regular unsorted dictionary

1084-

>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

1085-1086-

>>> # dictionary sorted by key

1087-

>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))

1088-

OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

1089-1090-

>>> # dictionary sorted by value

1091-

>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))

1092-

OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

1093-1094-

>>> # dictionary sorted by length of the key string

1095-

>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))

1096-

OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

1097-1098-

The new sorted dictionaries maintain their sort order when entries

1099-

are deleted. But when new keys are added, the keys are appended

1100-

to the end and the sort is not maintained.

1101-1102-

It is also straight-forward to create an ordered dictionary variant

1104+

It is straightforward to create an ordered dictionary variant

11031105

that remembers the order the keys were *last* inserted.

11041106

If a new entry overwrites an existing entry, the

11051107

original insertion position is changed and moved to the end::

@@ -1108,21 +1110,29 @@ original insertion position is changed and moved to the end::

11081110

'Store items in the order the keys were last added'

1109111111101112

def __setitem__(self, key, value):

1111-

if key in self:

1112-

del self[key]

1113-

OrderedDict.__setitem__(self, key, value)

1113+

super().__setitem__(key, value)

1114+

super().move_to_end(key)

111411151115-

An ordered dictionary can be combined with the :class:`Counter` class

1116-

so that the counter remembers the order elements are first encountered::

1116+

An :class:`OrderedDict` would also be useful for implementing

1117+

variants of :func:`functools.lru_cache`::

111711181118-

class OrderedCounter(Counter, OrderedDict):

1119-

'Counter that remembers the order elements are first encountered'

1119+

class LRU(OrderedDict):

1120+

'Limit size, evicting the least recently looked-up key when full'

112011211121-

def __repr__(self):

1122-

return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

1122+

def __init__(self, maxsize=128, *args, **kwds):

1123+

self.maxsize = maxsize

1124+

super().__init__(*args, **kwds)

112311251124-

def __reduce__(self):

1125-

return self.__class__, (OrderedDict(self),)

1126+

def __getitem__(self, key):

1127+

value = super().__getitem__(key)

1128+

self.move_to_end(key)

1129+

return value

1130+1131+

def __setitem__(self, key, value):

1132+

super().__setitem__(key, value)

1133+

if len(self) > self.maxsize:

1134+

oldest = next(iter(self))

1135+

del self[oldest]

112611361127113711281138

:class:`UserDict` objects