This is half a new feature proposition, and half a doc update proposition.
I’m using the collections.Counter class, and I wanted to initialize a Counter with a series of keys being set to some integral value, let’s take 3 for example. I discovered that Counter.fromkeys is completely inactivated, and that workarounds using the Counter constructor are advised instead.
The reason at first glance is obvious : Counter relies on its values supporting addition, so a default value of None is a non-starter. So, I wondered, why not keep the method but make its value parameter required instead of optional ? In other words, why is
Counter.fromkeys(iterable, v) disabled even when I do provide a
Counter(iterable) * v would be a workaround if Counter supported that arraying of operators, but it doesn’t (and I think that shouldn’t change).
I dug into the code, and quickly observed that a difficulty would be to respect Counter’s take on multiplicity : if a key is repeated in an iterable, Counter will cumulate its default value. So, a dumb implementation as this :
@classmethod def fromkeys(cls, iterable, v): # notice v is not optional super().fromkeys(iterable, v)
… would fail to take repetitions into account.
I put together a simple implem for that, which requires an adaptation on the C version of the
_count_elements helper function but the idea is there. It can be found here.
However, I found that you already can do the version of this which doesn’t care about repetitions in the input iterable (which I don’t) in your code without modifying the stdlib, and without having to build one dict to be copied by the Counter. With this simple code :
super(Counter, Counter).fromkeys(iterable, v).
My doc proposition is this : if the change to Counter.fromkeys is deemed not a good idea for various reasons (which I can understand, the conditions on the default value are a bit weird : it must support addition with 0 and results of that addition), how about adding that line to the doc, as a documented workaround ?
I suspect some number of people must have come there wondering why the fromkeys method doesn’t work, so giving them a workaround would be a fair tradeoff for taking the method away.
So, adding that
super(Counter, Counter).fromkeys(iterable, v), and
Counter(iterable) if you don’t have a default value, and
Counter(iterable.keys()) if it’s a mapping. And too bad if you want both repetition of the input iterable to matter and a non-1 default value, you’ll have to do that yourself, but at least we offer help for the other cases.
What do you all think ?