
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.
Counter is a moot analogy. Counter's + and - operators follow the rules of numbers addition and subtraction:
c = Counter({"a": 1}) c + Counter({"a": 5}) Counter({'a': 6}) c + Counter({"a": 5}) - Counter({"a": 4}) Counter({'a': 2})
Which also means that in most cases (c1 + c2) - c2 == c1 which is not something you would expect with the suggested "dictionary addition" operation. As a side note, this is not true in general for Counters because of how subtraction handles 0. E.g.
c0 = Counter({"a": 0}) c1 = Counter({"a": 1}) (c0 + c1) - c1 Counter() (c0 + c1) - c1 == c0 False
--- The current intuition of how + and - work don't apply literally to this suggestion: 1) numeric types are their own story 2) most built-in sequences imply concatenation for + and have no subtraction 3) numpy-like arrays behave closer to numbers 4) Counters mimic numbers in some ways and while addition reminds of concatenation (but order is not relevant) they also have subtraction 5) sets have difference which is probably the closest you expect from dict subtraction, but no + operator --- I understand the arguments against a | operator for dicts but I don't entirely agree with them. dict is obviously a different type of object than all the others I've mentioned, even mathematically, and there is no clear precedent. If sets happened to maintain insertion order, like dicts after 3.6/3.7, I would expect the union operator to also preserve the order. Before 3.6 we probably would have seen dicts as closer to sets from that point of view, and this suggested addition as closer to set union. The question of symmetry ({"a": 1} + {"a": 2}) is an important one and I would consider not enforcing one resolution in PEP 584, and instead leave this undefined (i.e. in the resulting dict, the value could be either 1 or 2, or just completely undefined to also be compatible with Counter-like semantics in the same PEP). This is something to consider carefully if the plan is to make the new operators part of Mapping. It's not obvious that all mappings should implement this the same way, and a survey of what is being done by other implementation of Mappings would be useful. On the other hand leaving it undefined might make it harder to standardize it later, once other implementations have defined their own behavior. This question is probably on its own a valid argument against the proposal. When it comes to dicts (and not Mappings in general) {**d1, **d2} or d.update() already have clearly-defined semantics. The new proposal for a merge() operation might be more useful. The added value would be the ability to add two mappings regardless of concrete type. But it's with Mappings in general that this proposal is the most problematic. On the other hand the subtraction operator is probably less controversial and immediately useful (the idiom to remove keys from a dictionary is not obvious).