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

Tim Peters tim.peters at gmail.com
Mon Apr 16 12:21:51 EDT 2018


[Steve Barnes <gadgetsteve at live.co.uk>]
> Wouldn't it make sense to have the current counter behaviour, (negative
> counts not allowed), and also a counter that did allow negative values
> (my bank doesn't seem to have a problem with my balance being able to go
> below negative), and possibly at the same time a counter class that
> allowed fractional counts?

We already have all that:  a counter's values can be anything at all:

>>> a = Counter(a=Fraction(2, 3))
>>> a + a
Counter({'a': Fraction(4, 3)})

It's four specific binary "multiset" _operations_ that purge values <=
0 from their results:

>>> a = Counter(a=Fraction(-2, 3))
>>> a
Counter({'a': Fraction(-2, 3)})
>>> a['a'] < 0
True
>>> a + a
Counter()
>>> a - a
Counter()
>>> a | a
Counter()
>>> a & a
Counter()

OK, also unary prefix "+" and "-".

Other methods do not:

>>> a = Counter(a=Fraction(-2, 3))
>>> a.subtract(Counter(a=1))  # like inplace "-" but <= 0 not special
>>> a
Counter({'a': Fraction(-5, 3)})
>>> a.update(Counter(a=1)) # like inplace "+" but <= 0 not special
>>> a
Counter({'a': Fraction(-2, 3)})
>>> a['a'] -= 100
>>> a
Counter({'a': Fraction(-302, 3)})


> ...
> Likewise for a Counter that was allowed to be fractional the result of
> some_counter / scalar would have (potentially) fractional results and
> one that did not would give floor results.

As above, results are a property not of the counter objects, but of
the specific operations performed.  some_counter / scalar would most
obviously work like:the current:

>>> c = Counter(a=1, b=-2)
>>> c
Counter({'a': 1, 'b': -2})
>>> scalar = 5
>>> Counter({key: value / scalar for key, value in c.items()})
Counter({'a': 0.2, 'b': -0.4})


More information about the Python-ideas mailing list