Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f45abc9

Browse files
committed
Add method to OrderedDict for repositioning keys to the ends.
1 parent 7b2a771 commit f45abc9

5 files changed

Lines changed: 51 additions & 8 deletions

File tree

Doc/library/collections.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,23 @@ the items are returned in the order their keys were first added.
793793
(key, value) pair. The pairs are returned in LIFO order if *last* is true
794794
or FIFO order if false.
795795

796+
.. method:: move_to_end(key, last=True)
797+
798+
Move an existing *key* to either end of an ordered dictionary. The item
799+
is moved to the right end if *last* is true (the default) or to the
800+
beginning if *last* is false. Raises :exc:`KeyError` if the *key* does
801+
not exist::
802+
803+
>>> d = OrderedDict.fromkeys('abcde')
804+
>>> d.move_to_end('b')
805+
>>> ''.join(d.keys)
806+
'acdeb'
807+
>>> d.move_to_end('b', 0)
808+
>>> ''.join(d.keys)
809+
'bacde'
810+
811+
.. versionadded:: 3.2
812+
796813
In addition to the usual mapping methods, ordered dictionaries also support
797814
reverse iteration using :func:`reversed`.
798815

Lib/collections.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,29 @@ def __eq__(self, other):
173173
def __del__(self):
174174
self.clear() # eliminate cyclical references
175175

176-
def _renew(self, key, PREV=0, NEXT=1):
177-
'Fast version of self[key]=self.pop(key). Private method for internal use.'
176+
def move_to_end(self, key, last=True, PREV=0, NEXT=1):
177+
'''Move an existing element to the end (or beginning if last==False).
178+
179+
Raises KeyError if the element does not exist.
180+
When last=True, acts like a fast version of self[key]=self.pop(key).
181+
182+
'''
178183
link = self.__map[key]
179184
link_prev = link[PREV]
180185
link_next = link[NEXT]
181186
link_prev[NEXT] = link_next
182187
link_next[PREV] = link_prev
183188
root = self.__root
184-
last = root[PREV]
185-
link[PREV] = last
186-
link[NEXT] = root
187-
last[NEXT] = root[PREV] = link
189+
if last:
190+
last = root[PREV]
191+
link[PREV] = last
192+
link[NEXT] = root
193+
last[NEXT] = root[PREV] = link
194+
else:
195+
first = root[NEXT]
196+
link[PREV] = root
197+
link[NEXT] = first
198+
root[NEXT] = first[PREV] = link
188199

189200

190201
################################################################################

Lib/functools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def decorating_function(user_function, tuple=tuple, sorted=sorted,
127127
len=len, KeyError=KeyError):
128128
cache = OrderedDict() # ordered least recent to most recent
129129
cache_popitem = cache.popitem
130-
cache_renew = cache._renew
130+
cache_renew = cache.move_to_end
131131
kwd_mark = object() # separate positional and keyword args
132132
lock = Lock()
133133

Lib/test/test_collections.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,19 @@ def test_reinsert(self):
973973
od['a'] = 1
974974
self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
975975

976-
976+
def test_move_to_end(self):
977+
od = OrderedDict.fromkeys('abcde')
978+
self.assertEqual(list(od), list('abcde'))
979+
od.move_to_end('c')
980+
self.assertEqual(list(od), list('abdec'))
981+
od.move_to_end('c', 0)
982+
self.assertEqual(list(od), list('cabde'))
983+
od.move_to_end('c', 0)
984+
self.assertEqual(list(od), list('cabde'))
985+
od.move_to_end('e')
986+
self.assertEqual(list(od), list('cabde'))
987+
with self.assertRaises(KeyError):
988+
od.move_to_end('x')
977989

978990
class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
979991
type2test = OrderedDict

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Core and Builtins
1313
Library
1414
-------
1515

16+
- collections.OrderedDict now supports a new method for repositioning
17+
keys to either end.
18+
1619
- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
1720
test cases now also have assertWarns and assertWarnsRegexp methods to
1821
check that a given warning type was triggered by the code under test.

0 commit comments

Comments
 (0)