From 578c9211d6b57bbb3cc00ba6dd55893814168695 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 4 Apr 2014 15:19:36 +0300 Subject: Issue #19505: The items, keys, and values views of OrderedDict now support reverse iteration using reversed(). --- Doc/library/collections.rst | 3 +++ Lib/collections/__init__.py | 33 ++++++++++++++++++++++++++++++--- Lib/test/test_collections.py | 5 +++++ Misc/NEWS | 3 +++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index f5fe12a..06ba042 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -978,6 +978,9 @@ The :class:`OrderedDict` constructor and :meth:`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. +.. versionchanged:: 3.5 + The items, keys, and values :term:`views ` of :class:`OrderedDict` now + support reverse iteration using :func:`reversed`. :class:`OrderedDict` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index d6deb6a..3605cc3 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -20,6 +20,23 @@ from reprlib import recursive_repr as _recursive_repr ### OrderedDict ################################################################################ +class _OrderedDictKeysView(KeysView): + + def __reversed__(self): + yield from reversed(self._mapping) + +class _OrderedDictItemsView(ItemsView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield (key, self._mapping[key]) + +class _OrderedDictValuesView(ValuesView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield self._mapping[key] + class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' @@ -162,9 +179,19 @@ class OrderedDict(dict): return size update = __update = MutableMapping.update - keys = MutableMapping.keys - values = MutableMapping.values - items = MutableMapping.items + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return _OrderedDictKeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return _OrderedDictItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return _OrderedDictValuesView(self) + __ne__ = MutableMapping.__ne__ __marker = object() diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index ee28a6c..d352d2a 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1187,6 +1187,11 @@ class TestOrderedDict(unittest.TestCase): self.assertEqual(list(od.items()), pairs) self.assertEqual(list(reversed(od)), [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.keys())), + [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.values())), + [t[1] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) def test_popitem(self): pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] diff --git a/Misc/NEWS b/Misc/NEWS index 5466267..a1bb6c2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -29,6 +29,9 @@ Core and Builtins Library ------- +- Issue #19505: The items, keys, and values views of OrderedDict now support + reverse iteration using reversed(). + - Issue #21149: Improved thread-safety in logging cleanup during interpreter shutdown. Thanks to Devin Jeanpierre for the patch. -- cgit v0.12