negative "counts" in collections.Counter?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Mon Mar 8 07:21:18 EST 2010


On Sun, 07 Mar 2010 22:31:00 -0800, Raymond Hettinger wrote:

> On Mar 7, 5:46 pm, Steven D'Aprano <st... at REMOVE-THIS-
> cybersource.com.au> wrote:
>> Given that Counter supports negative counts, it looks to me that the
>> behaviour of __add__ and __sub__ is fundamentally flawed. You should
>> raise a bug report (feature enhancement) on the bug tracker.
> 
> It isn't a bug.  I designed it that way. There were several possible
> design choices, each benefitting different use cases.

Thanks for the explanation Raymond. A few comments follow:


> FWIW, here is the reasoning behind the design.
> 
> The basic approach to Counter() is to be a dict subclass that supplies
> zero for missing values.   This approach places almost no restrictions
> on what can be stored in it. You can store floats, decimals, fractions,
> etc. Numbers can be positive, negative, or zero.

Another way of using default values in a dict. That's five that I know 
of: dict.get, dict.setdefault, dict.pop, collections.defaultdict, and 
collections.Counter. And the Perl people criticise Python for having 
"only one way to do it" *wink*

(That's not meant as a criticism, merely an observation.)


[...]
> One possible choice (the one preferred by the OP) was to has addition
> and subtraction be straight adds and subtracts without respect to sign
> and to not support __and__ and __or__. Straight addition was already
> supported via the update() method. But no direct support was provided
> for straight subtractions that leave negative values.  Sorry about that.

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.


> Instead the choice was to implement the four methods as multiset
> operations.  As such, they need to correspond to regular set operations.

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?



-- 
Steven



More information about the Python-list mailing list