Counter.update / subtract
Unlike dict.update, Counter.update ADDS counts instead of replacing them. subtract is the mirror image and — unlike the - operator — keeps zero and negative results.
Common call
c.update(['a', 'b']) · c.subtract('a')
Returns
None — the Counter itself changes
Replaces
a loop of c[x] += 1 / c[x] -= 1
Watch out
a str argument is counted per character
Counter.update(iterableiterable — Elements to count once each, or a mapping whose values are added (update) or subtracted (subtract).type: iterable | mapping · default: None=None, /, **kwds)
→ None
Demo
Live evaluation
Counts from the second text are added to the first.
Try:
Inputs
astrinitial letters
bstrletters to add
Code
from collections import Counter c = Counter('aab') c.update('abc') c
Result
Counter({'a': 3, 'b': 2, 'c': 1})
With "aab" minus "abbc", subtract() leaves a: 1, b: -1, c: -1 — every element it touched stays in the Counter. The - operator on the same inputs returns only a: 1, and when everything cancels it returns an empty Counter().
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| iterable | iterable | mapping | no (None) | Elements to count once each, or a mapping whose values are added (update) or subtracted (subtract). |
| **kwds | int | no | Counts as keyword arguments: c.update(a=2). |
Return value
None — Both methods change the Counter in place.
Common patterns
Count a stream in batches
update() keeps adding to the running totals.
from collections import Counter totals = Counter() for batch in batches: totals.update(batch)
Merge count dicts
A mapping argument adds its values.
from collections import Counter inventory = Counter(apples=3) inventory.update({"apples": 2, "pears": 4})
Stock left after orders
subtract keeps negatives, so shortages stay visible.
from collections import Counter stock.subtract(order) short = {item: -n for item, n in stock.items() if n < 0}
Examples
1. update adds, it does not replace
from collections import Counter
c = Counter(a=1)
c.update({'a': 5})
c
Returns
Counter({'a': 6})2. dict.update would replace
d = {'a': 1}
d.update({'a': 5})
d
Returns
{'a': 5}3. Keyword counts
from collections import Counter
c = Counter()
c.update(x=2, y=1)
c
Returns
Counter({'x': 2, 'y': 1})4. An iterable counts once per element
from collections import Counter
c = Counter(['a'])
c.update(['a', 'b', 'a'])
c
Returns
Counter({'a': 3, 'b': 1})5. subtract keeps negatives
from collections import Counter
c = Counter(a=4, b=2)
c.subtract(a=1, b=5)
c
Returns
Counter({'a': 3, 'b': -3})6. Both return None
from collections import Counter
print(Counter().update('abc'))
Returns
NonePitfalls
1. Passing one word as a string
update iterates its argument, so a str adds one count per character. Wrap a single element in a list.
update('cat')
from collections import Counter c = Counter() c.update('cat') c
Counter({'c': 1, 'a': 1, 't': 1})
update(['cat'])
from collections import Counter c = Counter() c.update(['cat']) c
Counter({'cat': 1})
2. Assigning the result
update and subtract return None; the Counter you called them on is the result.
c = c.update(...)
from collections import Counter c = Counter('ab') c = c.update('b') c is None
True
call, then use c
from collections import Counter c = Counter('ab') c.update('b') c
Counter({'b': 2, 'a': 1})
When to use
Use it
- Accumulating counts over several inputs
- Inventory or budget arithmetic where negative results matter (subtract)
Reach for something else
- Replacing counts → c[key] = value (or dict.update semantics)
- Combining without keeping zero/negative results → the + and - operators
Notes
CPython impl
Lib/collections/__init__.py — iterables go through the C helper _count_elements; mappings are added item by item (an empty Counter updated with a mapping just copies it)
Versions
update since 3.1, subtract added in 3.2 (docs.python.org)
Counts
Values may be any numbers; update/subtract never drop an element, even at 0
FAQ
dict.update overwrites values for existing keys. Counter.update adds the new counts to the existing ones, and an iterable argument counts its elements instead of expecting key/value pairs.