[Python-ideas] Dict joining using + and +=

Serhiy Storchaka storchaka at gmail.com
Fri Mar 1 01:47:36 EST 2019

01.03.19 06:21, Guido van Rossum пише:
> On Wed, Feb 27, 2019 at 11:18 PM Serhiy Storchaka 
> <storchaka at gmail.com 
> <mailto:storchaka at gmail.com>> wrote:
>     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.

Currently Counter += dict works and Counter + dict is an error. With 
this change Counter + dict will return a value, but it will be different 
from the result of the += operator.

Also, if the custom dict subclass implemented the plus operator with 
different semantic which supports the addition with a dict, this change 
will break it, because dict + CustomDict will call dict.__add__ instead 
of CustomDict.__radd__. Adding support of new operators to builting 
types is dangerous.

>     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.

And this saves us from the hard problem of creating a mapping of the 
same type. Note that reference implementations discussed above make d1 + 
d2 always returning a dict. dict.copy() returns a dict.

> 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.

Perhaps the better solution is to update the documentation.

More information about the Python-ideas mailing list