negative "counts" in collections.Counter?

Raymond Hettinger python at rcn.com
Mon Mar 8 14:24:02 EST 2010


[Steven D'Aprano]
> Thanks for the explanation Raymond. A few comments follow:

You're welcome :-)


> Would you consider a feature enhancement adding an additional method,
> analogous to update(), to perform subtractions? I recognise that it's
> easy to subclass and do it yourself, but there does seem to be some
> demand for it, and it is an obvious feature given that Counter does
> support negative counts.

Will continue to mull it over.

Instinct says that conflating two models can be worse for usability
than just picking one of the models and excluding the other.

If I had it to do over, there is a reasonable case that elementwise
vector methods (__add__, __sub__, and __mul__) may have been a more
useful choice than multiset methods (__add__, __sub__, __and__,
__or__).

That being said, the multiset approach was the one that was chosen.
It was indicated for people who have experience with bags or
multisets in other languages.   It was also consistent with the naming
of the class as tool for counting things (i.e. it handles counting
numbers right out of the box).  No explicit support is provided
for negative values, but it isn't actively hindered either.

For applications needing elementwise vector operations and signed
arithmetic, arguably they should be using a more powerful toolset,
perhaps supporting a full-range of elementwise binary and unary
operations and a dotproduct() method.  Someone should write that
class and post it to the ASPN Cookbook to see if there is any uptake.


> Personally, I think the behaviour of + and - would be far less surprising
> if the class was called Multiset. Intuitively, one would expect counters
> to be limited to ints, and to support negative counts when adding and
> subtracting. In hindsight, do you think that Multiset would have been a
> better name?

The primary use case for Counter() is to count things (using the
counting numbers).
The term Multiset is more obscure and only applies
to the four operations that eliminate non-positive results.
So, I'm somewhat happy with the current name.

FWIW, the notion of "what is surprising" often depends on the
observer's
background and on the problem they are currently trying to solve.
If you need negative counts, then Counter.__sub__() is surprising.
If your app has no notion of a negative count, then it isn't.
The docs, examples, and docstrings are very clear about the behavior,
so the "surprise" is really about wanting it to do something other
than what it currently does ;-)


Raymond






More information about the Python-list mailing list