diff options
author | Raymond Hettinger <python@rcn.com> | 2011-04-17 20:08:41 -0700 |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2011-04-17 20:08:41 -0700 |
commit | efeb8bdaa2102208e765610fc2f84482b321ef5b (patch) | |
tree | b72dbeac10c40ba90cf5b2abd746c615de0ed549 | |
parent | c116da04a96f173230fa8635adb69a1d83d21c0d (diff) | |
download | cpython-git-efeb8bdaa2102208e765610fc2f84482b321ef5b.tar.gz |
Rework multiset methods to use less memory and to make fewer calls to __hash__.
-rw-r--r-- | Lib/collections.py | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/Lib/collections.py b/Lib/collections.py index cb720ac9ab..3c54690eb5 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -552,10 +552,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): @@ -568,10 +571,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): @@ -584,11 +590,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): @@ -601,11 +610,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 _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 |