mirror of
https://github.com/python/cpython.git
synced 2025-10-13 10:23:28 +00:00
Add method to OrderedDict for repositioning keys to the ends.
This commit is contained in:
parent
7b2a7710ef
commit
f45abc97bf
5 changed files with 51 additions and 8 deletions
|
@ -793,6 +793,23 @@ the items are returned in the order their keys were first added.
|
||||||
(key, value) pair. The pairs are returned in LIFO order if *last* is true
|
(key, value) pair. The pairs are returned in LIFO order if *last* is true
|
||||||
or FIFO order if false.
|
or FIFO order if false.
|
||||||
|
|
||||||
|
.. method:: move_to_end(key, 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 :exc:`KeyError` if the *key* does
|
||||||
|
not exist::
|
||||||
|
|
||||||
|
>>> d = OrderedDict.fromkeys('abcde')
|
||||||
|
>>> d.move_to_end('b')
|
||||||
|
>>> ''.join(d.keys)
|
||||||
|
'acdeb'
|
||||||
|
>>> d.move_to_end('b', 0)
|
||||||
|
>>> ''.join(d.keys)
|
||||||
|
'bacde'
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
In addition to the usual mapping methods, ordered dictionaries also support
|
In addition to the usual mapping methods, ordered dictionaries also support
|
||||||
reverse iteration using :func:`reversed`.
|
reverse iteration using :func:`reversed`.
|
||||||
|
|
||||||
|
|
|
@ -173,18 +173,29 @@ class OrderedDict(dict, MutableMapping):
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.clear() # eliminate cyclical references
|
self.clear() # eliminate cyclical references
|
||||||
|
|
||||||
def _renew(self, key, PREV=0, NEXT=1):
|
def move_to_end(self, key, last=True, PREV=0, NEXT=1):
|
||||||
'Fast version of self[key]=self.pop(key). Private method for internal use.'
|
'''Move an existing element to the end (or beginning if last==False).
|
||||||
|
|
||||||
|
Raises KeyError if the element does not exist.
|
||||||
|
When last=True, acts like a fast version of self[key]=self.pop(key).
|
||||||
|
|
||||||
|
'''
|
||||||
link = self.__map[key]
|
link = self.__map[key]
|
||||||
link_prev = link[PREV]
|
link_prev = link[PREV]
|
||||||
link_next = link[NEXT]
|
link_next = link[NEXT]
|
||||||
link_prev[NEXT] = link_next
|
link_prev[NEXT] = link_next
|
||||||
link_next[PREV] = link_prev
|
link_next[PREV] = link_prev
|
||||||
root = self.__root
|
root = self.__root
|
||||||
last = root[PREV]
|
if last:
|
||||||
link[PREV] = last
|
last = root[PREV]
|
||||||
link[NEXT] = root
|
link[PREV] = last
|
||||||
last[NEXT] = root[PREV] = link
|
link[NEXT] = root
|
||||||
|
last[NEXT] = root[PREV] = link
|
||||||
|
else:
|
||||||
|
first = root[NEXT]
|
||||||
|
link[PREV] = root
|
||||||
|
link[NEXT] = first
|
||||||
|
root[NEXT] = first[PREV] = link
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
@ -127,7 +127,7 @@ def lru_cache(maxsize=100):
|
||||||
len=len, KeyError=KeyError):
|
len=len, KeyError=KeyError):
|
||||||
cache = OrderedDict() # ordered least recent to most recent
|
cache = OrderedDict() # ordered least recent to most recent
|
||||||
cache_popitem = cache.popitem
|
cache_popitem = cache.popitem
|
||||||
cache_renew = cache._renew
|
cache_renew = cache.move_to_end
|
||||||
kwd_mark = object() # separate positional and keyword args
|
kwd_mark = object() # separate positional and keyword args
|
||||||
lock = Lock()
|
lock = Lock()
|
||||||
|
|
||||||
|
|
|
@ -973,7 +973,19 @@ class TestOrderedDict(unittest.TestCase):
|
||||||
od['a'] = 1
|
od['a'] = 1
|
||||||
self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
|
self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
|
||||||
|
|
||||||
|
def test_move_to_end(self):
|
||||||
|
od = OrderedDict.fromkeys('abcde')
|
||||||
|
self.assertEqual(list(od), list('abcde'))
|
||||||
|
od.move_to_end('c')
|
||||||
|
self.assertEqual(list(od), list('abdec'))
|
||||||
|
od.move_to_end('c', 0)
|
||||||
|
self.assertEqual(list(od), list('cabde'))
|
||||||
|
od.move_to_end('c', 0)
|
||||||
|
self.assertEqual(list(od), list('cabde'))
|
||||||
|
od.move_to_end('e')
|
||||||
|
self.assertEqual(list(od), list('cabde'))
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
od.move_to_end('x')
|
||||||
|
|
||||||
class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
|
class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
|
||||||
type2test = OrderedDict
|
type2test = OrderedDict
|
||||||
|
|
|
@ -13,6 +13,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- collections.OrderedDict now supports a new method for repositioning
|
||||||
|
keys to either end.
|
||||||
|
|
||||||
- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
|
- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
|
||||||
test cases now also have assertWarns and assertWarnsRegexp methods to
|
test cases now also have assertWarns and assertWarnsRegexp methods to
|
||||||
check that a given warning type was triggered by the code under test.
|
check that a given warning type was triggered by the code under test.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue