]> granicus.if.org Git - python/commitdiff
Make OrderedDict.popitem() a bit smarter and faster
authorRaymond Hettinger <python@rcn.com>
Thu, 2 Sep 2010 18:44:16 +0000 (18:44 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 2 Sep 2010 18:44:16 +0000 (18:44 +0000)
Lib/collections.py

index 6daa5967c1205f789210d7e956058f5825bb0f37..fb6766e2a54ea385340f35ee006672daa782a6d5 100644 (file)
@@ -108,25 +108,37 @@ class OrderedDict(dict, MutableMapping):
             pass
         dict.clear(self)
 
-    setdefault = MutableMapping.setdefault
-    update = MutableMapping.update
-    pop = MutableMapping.pop
-    keys = MutableMapping.keys
-    values = MutableMapping.values
-    items = MutableMapping.items
-    __ne__ = MutableMapping.__ne__
-
-    def popitem(self, last=True):
+    def popitem(self, last=True, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
         '''od.popitem() -> (k, v), return and remove a (key, value) pair.
         Pairs are returned in LIFO order if last is true or FIFO order if false.
 
         '''
         if not self:
             raise KeyError('dictionary is empty')
-        key = next(reversed(self) if last else iter(self))
-        value = self.pop(key)
+        root = self.__root
+        if last:                    # link_prev <--> link <--> root
+            link = root[PREV]
+            link_prev = link[PREV]
+            link_prev[NEXT] = root
+            root[PREV] = link_prev
+        else:                       # root <--> link <--> link_next
+            link = root[NEXT]
+            link_next = link[NEXT]
+            root[NEXT] = link_next
+            link_next[PREV] = root
+        key = link[KEY]
+        del self.__map[key]
+        value = dict_pop(self, key)
         return key, value
 
+    setdefault = MutableMapping.setdefault
+    update = MutableMapping.update
+    pop = MutableMapping.pop
+    keys = MutableMapping.keys
+    values = MutableMapping.values
+    items = MutableMapping.items
+    __ne__ = MutableMapping.__ne__
+
     def __repr__(self):
         'od.__repr__() <==> repr(od)'
         if not self: