[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