[Python-checkins] cpython (2.7): Rework multiset methods to use less memory and to make fewer calls to __hash__.

raymond.hettinger python-checkins at python.org
Mon Apr 18 05:08:49 CEST 2011


http://hg.python.org/cpython/rev/0c7ea87f676a
changeset:   69416:0c7ea87f676a
branch:      2.7
parent:      69411:d683ff1d6866
user:        Raymond Hettinger <python at rcn.com>
date:        Sun Apr 17 20:08:41 2011 -0700
summary:
  Rework multiset methods to use less memory and to make fewer calls to __hash__.

files:
  Lib/collections.py |  31 +++++++++++++++++++------------
  1 files changed, 19 insertions(+), 12 deletions(-)


diff --git a/Lib/collections.py b/Lib/collections.py
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -552,10 +552,13 @@
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
-        for elem in set(self) | set(other):
-            newcount = self[elem] + other[elem]
+        for elem, count in self.items():
+            newcount = count + other[elem]
             if newcount > 0:
                 result[elem] = newcount
+        for elem, count in other.items():
+            if elem not in self and count > 0:
+                result[elem] = count
         return result
 
     def __sub__(self, other):
@@ -568,10 +571,13 @@
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
-        for elem in set(self) | set(other):
-            newcount = self[elem] - other[elem]
+        for elem, count in self.items():
+            newcount = count - other[elem]
             if newcount > 0:
                 result[elem] = newcount
+        for elem, count in other.items():
+            if elem not in self and count < 0:
+                result[elem] = 0 - count
         return result
 
     def __or__(self, other):
@@ -584,11 +590,14 @@
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
-        for elem in set(self) | set(other):
-            p, q = self[elem], other[elem]
-            newcount = q if p < q else p
+        for elem, count in self.items():
+            other_count = other[elem]
+            newcount = other_count if count < other_count else count
             if newcount > 0:
                 result[elem] = newcount
+        for elem, count in other.items():
+            if elem not in self and count > 0:
+                result[elem] = count
         return result
 
     def __and__(self, other):
@@ -601,11 +610,9 @@
         if not isinstance(other, Counter):
             return NotImplemented
         result = Counter()
-        if len(self) < len(other):
-            self, other = other, self
-        for elem in _ifilter(self.__contains__, other):
-            p, q = self[elem], other[elem]
-            newcount = p if p < q else q
+        for elem, count in self.items():
+            other_count = other[elem]
+            newcount = count if count < other_count else other_count
             if newcount > 0:
                 result[elem] = newcount
         return result

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list