diff options
author | Raymond Hettinger <python@rcn.com> | 2011-10-19 20:40:37 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2011-10-19 20:40:37 (GMT) |
commit | becd56822ac62ba2ddb4956e84f6854366945617 (patch) | |
tree | f1a399031f43a18d7784fe8f0c47d434320edb92 /Lib/collections/__init__.py | |
parent | 3bb8be6d78130dfcf49c4860f0009300508ff92b (diff) | |
download | cpython-becd56822ac62ba2ddb4956e84f6854366945617.zip cpython-becd56822ac62ba2ddb4956e84f6854366945617.tar.gz cpython-becd56822ac62ba2ddb4956e84f6854366945617.tar.bz2 |
Issue #13121: Support in-place math operators for collections.Counter().
Diffstat (limited to 'Lib/collections/__init__.py')
-rw-r--r-- | Lib/collections/__init__.py | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 3e864b6..68b63a8 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -683,6 +683,69 @@ class Counter(dict): ''' return Counter() - self + def _keep_positive(self): + '''Internal method to strip elements with a negative or zero count''' + nonpositive = [elem for elem, count in self.items() if not count > 0] + for elem in nonpositive: + del self[elem] + return self + + def __iadd__(self, other): + '''Inplace add from another counter, keeping only positive counts. + + >>> c = Counter('abbb') + >>> c += Counter('bcc') + >>> c + Counter({'b': 4, 'c': 2, 'a': 1}) + + ''' + for elem, count in other.items(): + self[elem] += count + return self._keep_positive() + + def __isub__(self, other): + '''Inplace subtract counter, but keep only results with positive counts. + + >>> c = Counter('abbbc') + >>> c -= Counter('bccd') + >>> c + Counter({'b': 2, 'a': 1}) + + ''' + for elem, count in other.items(): + self[elem] -= count + return self._keep_positive() + + def __ior__(self, other): + '''Inplace union is the maximum of value from either counter. + + >>> c = Counter('abbb') + >>> c |= Counter('bcc') + >>> c + Counter({'b': 3, 'c': 2, 'a': 1}) + + ''' + for elem, other_count in other.items(): + count = self[elem] + if other_count > count: + self[elem] = other_count + return self._keep_positive() + + def __iand__(self, other): + '''Inplace intersection is the minimum of corresponding counts. + + >>> c = Counter('abbb') + >>> c &= Counter('bcc') + >>> c + Counter({'b': 1}) + + ''' + for elem, count in self.items(): + other_count = other[elem] + if other_count < count: + self[elem] = other_count + return self._keep_positive() + ######################################################################## ### ChainMap (helper for configparser and string.Template) |