mirror of https://github.com/python/cpython
Add method to OrderedDict for repositioning keys to the ends.
This commit is contained in:
parent
7b2a7710ef
commit
f45abc97bf
|
@ -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
|
||||
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
|
||||
reverse iteration using :func:`reversed`.
|
||||
|
||||
|
|
|
@ -173,18 +173,29 @@ class OrderedDict(dict, MutableMapping):
|
|||
def __del__(self):
|
||||
self.clear() # eliminate cyclical references
|
||||
|
||||
def _renew(self, key, PREV=0, NEXT=1):
|
||||
'Fast version of self[key]=self.pop(key). Private method for internal use.'
|
||||
def move_to_end(self, key, last=True, PREV=0, NEXT=1):
|
||||
'''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_prev = link[PREV]
|
||||
link_next = link[NEXT]
|
||||
link_prev[NEXT] = link_next
|
||||
link_next[PREV] = link_prev
|
||||
root = self.__root
|
||||
last = root[PREV]
|
||||
link[PREV] = last
|
||||
link[NEXT] = root
|
||||
last[NEXT] = root[PREV] = link
|
||||
if last:
|
||||
last = root[PREV]
|
||||
link[PREV] = last
|
||||
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):
|
||||
cache = OrderedDict() # ordered least recent to most recent
|
||||
cache_popitem = cache.popitem
|
||||
cache_renew = cache._renew
|
||||
cache_renew = cache.move_to_end
|
||||
kwd_mark = object() # separate positional and keyword args
|
||||
lock = Lock()
|
||||
|
||||
|
|
|
@ -973,7 +973,19 @@ class TestOrderedDict(unittest.TestCase):
|
|||
od['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):
|
||||
type2test = OrderedDict
|
||||
|
|
|
@ -13,6 +13,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- collections.OrderedDict now supports a new method for repositioning
|
||||
keys to either end.
|
||||
|
||||
- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
|
||||
test cases now also have assertWarns and assertWarnsRegexp methods to
|
||||
check that a given warning type was triggered by the code under test.
|
||||
|
|
Loading…
Reference in New Issue