On Wed, Feb 27, 2019 at 11:18 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
27.02.19 20:48, Guido van Rossum пише:
On Wed, Feb 27, 2019 at 10:42 AM Michael Selik <mike@selik.org <mailto:mike@selik.org>> wrote > The dict subclass
collections.Counter overrides the update method
for adding values instead of overwriting values.
https://docs.python.org/3/library/collections.html#collections.Counter.updat...
Counter also uses +/__add__ for a similar behavior.
>>> c = Counter(a=3, b=1) >>> d = Counter(a=1, b=2) >>> c + d # add two counters together: c[x] + d[x] Counter({'a': 4, 'b': 3})
At first I worried that changing base dict would cause confusion for the subclass, but Counter seems to share the idea that update and + are synonyms.
Great, this sounds like a good argument for + over |. The other argument is that | for sets *is* symmetrical, while + is used for other collections where it's not symmetrical. So it sounds like + is a winner here.
Counter uses + for a *different* behavior!
Counter(a=2) + Counter(a=3) Counter({'a': 5})
Well, you can see this as a special case. The proposed + operator on Mappings returns a new Mapping whose keys are the union of the keys of the two arguments; the value is the single value for a key that occurs in only one of the arguments, and *somehow* combined for a key that's in both. The way of combining keys is up to the type of Mapping. For dict, the second value wins (not so different as {'a': 1, 'a': 2}, which becomes {'a': 2}). But for other Mappings, the combination can be done differently -- and Counter chooses to add the two values.
I do not understand why we discuss a new syntax for dict merging if we already have a syntax for dict merging: {**d1, **d2} (which works with *all* mappings). Is not this contradicts the Zen?
But (as someone else pointed out) {**d1, **d2} always returns a dict, not the type of d1 and d2. Also, I'm sorry for PEP 448, but even if you know about **d in simpler contexts, if you were to ask a typical Python user how to combine two dicts into a new one, I doubt many people would think of {**d1, **d2}. I know I myself had forgotten about it when this thread started! If you were to ask a newbie who has learned a few things (e.g. sequence concatenation) they would much more likely guess d1+d2. The argument for + over | has been mentioned elsewhere already. @Eric Smith <eric@trueblade.com>
I'd help out.
Please do! I tried to volunteer Stephen d'Aprano but I think he isn't interested in pushing through a controversial PEP. The PEP should probably also propose d1-d2. -- --Guido van Rossum (python.org/~guido)