This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: collections.Counter drops key if value is 0 and updating using += operator
Type: behavior Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: Dennis Sweeney, crypdick, rhettinger
Priority: normal Keywords:

Created on 2021-11-30 02:43 by crypdick, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg407348 - (view) Author: Richard Decal (crypdick) Date: 2021-11-30 02:43
In brief:

```
from collections import Counter
x = Counter({'a': 0, 'b': 1})
x.update(x)  # works: Counter({'a': 0, 'b': 2})
x += x  # expected: Counter({'a': 0, 'b': 3}) actual: Counter({'b': 3})
```

I expect `+=` and `.update()` to be synonymous. However, the += operator is deleting keys if the source Counter has a zero count to begin with:

```
x = Counter({'a': 1})
x += Counter({'a': 0})  # ok: Counter({'a': 1})

y = Counter({'a': 0})
y += y  # expected: Counter({'a': 0}) actual: Counter()
```
msg407349 - (view) Author: Dennis Sweeney (Dennis Sweeney) * (Python committer) Date: 2021-11-30 03:29
This is consistent with the docstrings of the methods:

---------------------------------------------------------------------
>>> help(Counter.__iadd__)
Help on function __iadd__ in module collections:

__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})

>>> help(Counter.update)
Help on function update in module collections:

update(self, iterable=None, /, **kwds)
    Like dict.update() but add counts instead of replacing them.
    
    Source can be an iterable, a dictionary, or another Counter instance.
    
    >>> c = Counter('which')
    >>> c.update('witch')           # add elements from another iterable
    >>> d = Counter('watch')
    >>> c.update(d)                 # add elements from another counter
    >>> c['h']                      # four 'h' in which, witch, and watch
    4
---------------------------------------------------------------------


However, it seems Counter.__iadd__ is not mentioned at all at https://docs.python.org/3/library/collections.html#collections.Counter. I think there could be a doc update.
msg407351 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-11-30 03:46
I don't think there is a need to list the inplace methods.  They were put in to optimize what was already occurring when only the __add__ method was defined.  Also, other container typically don't specifically call out the inplace methods.
History
Date User Action Args
2022-04-11 14:59:53adminsetgithub: 90094
2021-11-30 03:47:26rhettingersetassignee: rhettinger
2021-11-30 03:46:38rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg407351

resolution: not a bug
stage: resolved
2021-11-30 03:29:37Dennis Sweeneysetnosy: + Dennis Sweeney
messages: + msg407349
2021-11-30 02:43:03crypdickcreate