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

```
On 16/04/2018 06:07, Tim Peters wrote:
> [Peter Norvig]
>> For most types that implement __add__, `x + x` is equal to `2 * x`.
>>
>> That is true for all numbers, list, tuple, str, timedelta, etc. -- but not
>> for collections.Counter. I can add two Counters, but I can't multiply one
>> by a scalar. That seems like an oversight.
>>
>> ...
>> Here's an implementation:
>>
>>     def __mul__(self, scalar):
>>         "Multiply each entry by a scalar."
>>         result = Counter()
>>         for key in self:
>>             result[key] = self[key] * scalar
>>         return result
>>
>>     def __rmul__(self, scalar):
>>         "Multiply each entry by a scalar."
>>         result = Counter()
>>         for key in self:
>>             result[key] = scalar * self[key]
>>         return result
>
> Adding Counter * integer doesn't bother me a bit, but the definition
> of what that should compute isn't obvious.  In particular, that
> implementation doesn't preserve that `x+x == 2*x` if x has any
> negative values:
>
>>>> x = Counter(a=-1)
>>>> x
> Counter({'a': -1})
>>>> x+x
> Counter()
>
> It would be strange if x+x != 2*x, and if x*-1 != -x:
>
>>>> y = Counter(a=1)
>>>> y
> Counter({'a': 1})
>>>> -y
> Counter()
>
> Etc.
>
> Then again, it's already the case that, e.g., x-y isn't always the
> same as x + -y:
>
>>>> x = Counter(a=1)
>>>> y = Counter(a=2)
>>>> x - y
> Counter()
>>>> x + -y
> Counter({'a': 1})
>
> So screw obvious formal identities ;-)
>
> I'm not clear on why "+" and "-" discard keys with values <= 0 to
> begin with.  For "-" it's natural enough viewing "-" as being multiset
> difference, but for "+"?  That's just made up ;-)
>
> In any case, despite the oddities, I think your implementation would
> be least surprising overall (ignore the sign of the resulting values).
> At least for Counters that actually make sense as multisets (have no
> values <= 0), and for a positive integer multiplier `n > 0`, it does
> preserve that `x*n` = `x + x + ... + x` (with  `n` instances of `x`).
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
> ```
```
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?

Then:
>>>> x = Counter(a=1)
>>>> y = Counter(a=2)
>>>> x - y
> Counter()
>>>> x + -y
> Counter({'a': 1})
BUT:
>>>> x = Counter(a=1, allow_negative=True)
>>>> y = Counter(a=2, allow_negative=True)
>>>> x - y
> Counter({'a': 1})
>>>> x + -y
> Counter({'a': 1})
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.

--
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

---
This email has been checked for viruses by AVG.
http://www.avg.com

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
```