negative "counts" in collections.Counter?

Raymond Hettinger python at rcn.com
Mon Mar 8 17:44:38 EST 2010


[Gregory Ewing]
> I think you should be providing two types: one is a
> multiset, which disallows negative counts altogether;
> the other behaves like a sparse vector with appropriate
> arithmetic operations.


That is pretty close to what I said above:

"""
In this case, we have an indication that what you really want is a
separate class supporting elementwise binary and unary operations on
vectors (where the vector fields are accessed by a dictionary key
instead of a positional value).
"""

The first and foremost goal of the class was to provide a simple
counting capability along the lines of:

    class Counter(dict):
       def __init__(self, iterable=()):
            for elem in iterable:
                self[elem] += 1
       def __missing__(self, key):
            return 0

Note, there is no "disallowing negatives" or even any insistence
that the "counts" are actually numbers.  In that respect, it was
a consenting adults class from the start.  It is short, simple,
and fast.

The other methods were mostly just "extras" to make the tool
more useful.  Each adds its own minimal restrictions:

   elements() requires integer counts
   most_common() requires that counts be orderable
   multiset operations are defined for non-negative values

We could have kept this same design and wrapped every dictionary
method so that it would raise an exception for any count that was not
a positive integer.  That would have slowed down the class, increased
the code volume, and precluded some uses that are currently possible.
IMO, that would not have been a win and it would not have helped the
OP who was seeking a more vector-like tool for signed-number
operations.

Anyway, it is what it is.  The tool is released and most
users seem to be happy with what we have.


Raymond



More information about the Python-list mailing list