collections.Counter __add__ implementation quirk
collections.Counter.__add__ as a bit of a quirk. Counters allow for negative numbers. You can subtract from a counter into the negative no problem. However, if you have a counter with a negative value and add it to another counter, and if that value, after addition, would still be negative... that value is not included in the resulting Counter object. This is kind of weird, to the point of thinking I had a bug in other code for several hours until I went and checked how Counters are implemented. 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.
collections.Counter.__add__ as a bit of a quirk.
Counters allow for negative numbers. You can subtract from a counter into the negative no problem. However, if you have a counter with a negative value and add it to another counter, and if that value, after addition, would still be negative... that value is not included in the resulting Counter object. This is kind of weird, to the point of thinking I had a bug in other code for several hours until I went and checked how Counters are implemented.
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,
2015-11-23 7:21 GMT+01:00 Alexander Walters <tritium-list@sdamon.com>: 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).) hth, vbr
On Nov 23, 2015, at 10:43 AM, Vlastimil Brom <vlastimil.brom@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
Raymond, I think you made a typographical error in your Counter.update example. >>> 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) >>> c Counter({'a': 5, 'd': 4, 'c': -2, 'b': -3}) Pair programming ;-) On Tue, Nov 24, 2015 at 1:02 AM Raymond Hettinger < raymond.hettinger@gmail.com> wrote:
On Nov 23, 2015, at 10:43 AM, Vlastimil Brom <vlastimil.brom@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
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/mike%40selik.org
participants (4)
-
Alexander Walters
-
Michael Selik
-
Raymond Hettinger
-
Vlastimil Brom