From: Raymond Hettinger Date: Mon, 18 Apr 2011 02:49:29 +0000 (-0700) Subject: Rework multiset methods to use less memory and to make fewer calls to __hash__. X-Git-Tag: v3.3.0a1~2568 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=90375bc7c095f1bc7971f97f1082fc4851f62487;p=thirdparty%2FPython%2Fcpython.git Rework multiset methods to use less memory and to make fewer calls to __hash__. --- diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index bd19614a0178..a6bcaea5c43c 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -601,10 +601,13 @@ class Counter(dict): 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): @@ -617,10 +620,13 @@ class Counter(dict): 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): @@ -633,11 +639,14 @@ class Counter(dict): 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): @@ -650,11 +659,9 @@ class Counter(dict): if not isinstance(other, Counter): return NotImplemented result = Counter() - if len(self) < len(other): - self, other = other, self - for elem in filter(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