[Python-Dev] collections.Counter __add__ implementation quirk

Raymond Hettinger raymond.hettinger at gmail.com
Tue Nov 24 01:01:10 EST 2015


> On Nov 23, 2015, at 10:43 AM, Vlastimil Brom <vlastimil.brom at gmail.com> wrote:
> 
>> Is there any particular reason counters drop negative values when you add
>> them together?  I definitely expected them to act like ints do when you add
>> negatives, and had to subclass it to get what I think is the obvious
>> behavior.
>> _______________________________________________
>> Python-Dev mailing list
> ...
> Hi,
> this is probably more appropriate for the general python list rathere
> then this developers' maillist, however, as I asked a similar question
> some time ago, I got some detailed explanations for the the current
> design decissions from the original developer; cf.:
> https://mail.python.org/pipermail/python-list/2010-March/570618.html
> 
> (I didn't check possible changes in Counter since that version (3.1 at
> that time).)

In Python3.2, Counter grew a subtract() method:

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

The update() method has been around since the beginning:

>>> from collections import Counter
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=-5, c=-2, d=6)
>>> c.update(d)
>>> d
Counter({'d': 6, 'a': 1, 'c': -2, 'b': -5})


So, you have two ways of doing counter math:

1. Normal integer arithmetic using update() and subtract() does straight addition and subtraction, either starting with or ending-up with negative values.

2. Saturating arithmetic using the operators: + - & | excludes non-positive results.  This supports bag-like behavior (c.f. smalltalk) and multiset operations (https://en.wikipedia.org/wiki/Multiset).


Raymond








More information about the Python-Dev mailing list