mirror of https://github.com/python/cpython
Add a subtract() method to collections.Counter()
This commit is contained in:
parent
03d788dc4d
commit
9c01e441bb
|
@ -214,6 +214,17 @@ For example::
|
||||||
>>> Counter('abracadabra').most_common(3)
|
>>> Counter('abracadabra').most_common(3)
|
||||||
[('a', 5), ('r', 2), ('b', 2)]
|
[('a', 5), ('r', 2), ('b', 2)]
|
||||||
|
|
||||||
|
.. method:: subtract([iterable-or-mapping])
|
||||||
|
|
||||||
|
Elements are subtracted from an *iterable* or from another *mapping*
|
||||||
|
(or counter). Like :meth:`dict.update` but subtracts counts instead
|
||||||
|
of replacing them. Both inputs and outputs may be zero or negative.
|
||||||
|
|
||||||
|
>>> c = Counter(a=4, b=2, c=0, d=-2)
|
||||||
|
>>> d = Counter(a=1, b=2, c=3, d=4)
|
||||||
|
>>> c.subtract(d)
|
||||||
|
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
|
||||||
|
|
||||||
The usual dictionary methods are available for :class:`Counter` objects
|
The usual dictionary methods are available for :class:`Counter` objects
|
||||||
except for two which work differently for counters.
|
except for two which work differently for counters.
|
||||||
|
|
||||||
|
|
|
@ -436,6 +436,34 @@ class Counter(dict):
|
||||||
if kwds:
|
if kwds:
|
||||||
self.update(kwds)
|
self.update(kwds)
|
||||||
|
|
||||||
|
def subtract(self, iterable=None, **kwds):
|
||||||
|
'''Like dict.update() but subtracts counts instead of replacing them.
|
||||||
|
Counts can be reduced below zero. Both the inputs and outputs are
|
||||||
|
allowed to contain zero and negative counts.
|
||||||
|
|
||||||
|
Source can be an iterable, a dictionary, or another Counter instance.
|
||||||
|
|
||||||
|
>>> c = Counter('which')
|
||||||
|
>>> c.subtract('witch') # subtract elements from another iterable
|
||||||
|
>>> c.subtract(Counter('watch')) # subtract elements from another counter
|
||||||
|
>>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch
|
||||||
|
0
|
||||||
|
>>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch
|
||||||
|
-1
|
||||||
|
|
||||||
|
'''
|
||||||
|
if iterable is not None:
|
||||||
|
if isinstance(iterable, Mapping):
|
||||||
|
self_get = self.get
|
||||||
|
for elem, count in iterable.items():
|
||||||
|
self[elem] = self_get(elem, 0) - count
|
||||||
|
else:
|
||||||
|
self_get = self.get
|
||||||
|
for elem in iterable:
|
||||||
|
self[elem] = self_get(elem, 0) - 1
|
||||||
|
if kwds:
|
||||||
|
self.subtract(kwds)
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
'Like dict.copy() but returns a Counter instance instead of a dict.'
|
'Like dict.copy() but returns a Counter instance instead of a dict.'
|
||||||
return Counter(self)
|
return Counter(self)
|
||||||
|
|
|
@ -661,6 +661,16 @@ class TestCounter(unittest.TestCase):
|
||||||
set_result = setop(set(p.elements()), set(q.elements()))
|
set_result = setop(set(p.elements()), set(q.elements()))
|
||||||
self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
|
self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
|
||||||
|
|
||||||
|
def test_subtract(self):
|
||||||
|
c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
|
||||||
|
c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
|
||||||
|
self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
|
||||||
|
c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
|
||||||
|
c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
|
||||||
|
self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
|
||||||
|
c = Counter('aaabbcd')
|
||||||
|
c.subtract('aaaabbcce')
|
||||||
|
self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
|
||||||
|
|
||||||
class TestOrderedDict(unittest.TestCase):
|
class TestOrderedDict(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,8 @@ C-API
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Added a subtract() method to collections.Counter().
|
||||||
|
|
||||||
- Issue #8233: When run as a script, py_compile.py optionally takes a single
|
- Issue #8233: When run as a script, py_compile.py optionally takes a single
|
||||||
argument `-` which tells it to read files to compile from stdin. Each line
|
argument `-` which tells it to read files to compile from stdin. Each line
|
||||||
is read on demand and the named file is compiled immediately. (Original
|
is read on demand and the named file is compiled immediately. (Original
|
||||||
|
|
Loading…
Reference in New Issue