[Python-ideas] collections.Counter should implement __mul__, __rmul__

Tim Peters tim.peters at gmail.com
Mon Apr 16 20:43:55 EDT 2018


[Tim]
>> I also have no problem with inplace operators.  Or with adding
>> `Counter /= scalar", for that matter.

[Raymond]
> But surely __rdiv__() would be over the top, harmonic means be damned ;-)

Agreed - itertools.Counter is the poster child for "practicality beats
purity" :-)

In context, the

    c *= 1 / c.total

example would clearly be useful at times.  But it's a strained way to spell

    c /= c.total

and, for float values, the former also introduces a needless rounding
error (to compute the reciprocal).

BTW, if _`Counter * scalar` is added, we should think more about
oddball cases.  While everyone knows what _they_ mean by "scalar",
Python doesn't.  The obvious implementation (Peter already gave it)
would lead to things like `Counter * Counter`, where both
multiplicands have integer values, yielding a Counter whose values are
also Counters.

That is, if

    c = Counter(a=1, b=2)
    d = Counter(a=3, b=4)

then c*d would yield a Counter mapping 'a` to 1 * d == d, and 'b' to 2
* d == Counter(a=6, b=8).

That's "bad", because the next suggestion will be that c*d return
Counter(a=3, b=8) instead.  That is, map a shared key to the product
of the values associated with that key.  For example, `c` is a Counter
tabulating category counts, and `d` a Counter giving category weights.

I don't suggest doing that now, but it would be nice to dream up a way
to stop "things like" Counter * Counter at the start so that backward
compatibility doesn't preclude adding sensible meanings later.


More information about the Python-ideas mailing list