From fcb393c0183c6a8cf47eb9575a1bbe6bc5d236e4 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 9 Aug 2011 13:00:40 -0700 Subject: Add support for unary plus and unary minus to collections.Counter() --- Doc/library/collections.rst | 14 +++++++++++++- Lib/collections/__init__.py | 11 +++++++++++ Lib/test/test_collections.py | 5 +++++ Misc/NEWS | 2 ++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index f344b5a..df231f8 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -264,7 +264,7 @@ Common patterns for working with :class:`Counter` objects:: c.items() # convert to a list of (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n:-1] # n least common elements - c += Counter() # remove zero and negative counts + +c # remove zero and negative counts Several mathematical operations are provided for combining :class:`Counter` objects to produce multisets (counters that have counts greater than zero). @@ -284,6 +284,18 @@ counts, but the output will exclude results with counts of zero or less. >>> c | d # union: max(c[x], d[x]) Counter({'a': 3, 'b': 2}) +Unary addition and substraction are shortcuts for adding an empty counter +or subtracting from an empty counter. + + >>> c = Counter(a=2, b=-4) + >>> +c + Counter({'a': 2}) + >>> -c + Counter({'b': 4}) + +.. versionadded:: 3.3 + Added support for unary plus and unary minus. + .. note:: Counters were primarily designed to work with positive integers to represent diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 03bd2b3..2007e68 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -672,6 +672,17 @@ class Counter(dict): result[elem] = newcount return result + def __pos__(self): + 'Adds an empty counter, effectively stripping negative and zero counts' + return self + Counter() + + def __neg__(self): + '''Subtracts from an empty counter. Strips positive and zero counts, + and flips the sign on negative counts. + + ''' + return Counter() - self + ######################################################################## ### ChainMap (helper for configparser and string.Template) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index eb6d4d7..04c4d97 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -943,6 +943,11 @@ class TestCounter(unittest.TestCase): c.subtract('aaaabbcce') self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) + def test_unary(self): + c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) + self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) + self.assertEqual(dict(-c), dict(a=5)) + def test_helper_function(self): # two paths, one for real dicts and one for other mappings elems = list('abracadabra') diff --git a/Misc/NEWS b/Misc/NEWS index d257632..704e5e7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -252,6 +252,8 @@ Library - Issue #12540: Prevent zombie IDLE processes on Windows due to changes in os.kill(). +- Add support for unary plus and unary minus to collections.Counter(). + - Issue #12683: urlparse updated to include svn as schemes that uses relative paths. (svn from 1.5 onwards support relative path). -- cgit v0.12