Guido van Rossum wrote:
So the choice is really only three way. 1) Add d1 + d2 and d1 += d2 (using similarity with list + and +=) 2) Add d1 | d2 and d1 |= d2 (similar to set | and |=) 3) Do nothing We're not going to introduce a brand new operator for this purpose, nor are we going to use a different existing operator.
I didn't mean to argue for another operator, but rather to point out that i.m.o. "+" is not a good choice, for similar reasons why I think `collections.deque` shouldn't support "+" (regarding ambiguity of precedence and potential "loss" of data). Besides for `dict` even more interpretations of the meaning of "+" are plausible. Regarding "|" operator, I think a drawback is the resemblance with "or" (after all it's associated with "__or__") so people might assume behavior similar to `x or y` where `x` takes precedence (for truthy values of `x`). So when reading `d1 | d2` one could falsely assume that values in `d1` take precedence over the ones in `d2` for conflicting keys. And this is also the existing `set` behavior (though it's not really relevant in this case): >>> class Test: ... def __init__(self, x): ... self.x = x ... def __hash__(self): ... return 0 ... def __eq__(self, other): ... return True ... >>> s = {Test(1)} | {Test(2)} >>> s.pop().x # leftmost wins. 1
The asymmetry of the operation (in case there are matching keys with conflicting values) doesn't bother me, nor does the behavior of Counter affect how I feel about this. The += or |= operator will have to behave identical to d1.update(d2) when it comes to matching keys. I'm not sure whether += or |= needs to be an exact alias for dict.update. For lists, += and .extend() behave identically: both accept arbitrary sequences as right argument. But for sets, |= requires the right argument to be a set, while set.update() does not. (The not-in-place operators always require matching types: l1 + l2 requires l2 to be a list, s1 | s2 requires s2 to be a set.) But this is only a second-order consistency issue -- we should probably just follow the operator we're choosing in the end, either + or |. IMO the reason this is such a tough choice is that Python learners are typically introduced to list and dict early on, while sets are introduced later. However, the tutorial on docs.python.org covers sets before dicts -- but lists are covered much earlier, and dicts make some cameo appearances in the section on control flow. Perhaps more typical, the tutorial at https://www.tutorialspoint.com/python/ discusses data types in this order: numbers, strings, lists, tuples, dictionary, date&time -- it doesn't mention sets at all. This matches Python's historical development (sets weren't added until Python 2.3). So if we want to cater to what most beginners will know, + and += would be the best choice. But if we want to be more future-proof and consistent, | and |= are best -- after all dicts are closer to sets (both are hash tables) than to lists. (I know you can argue that dicts are closer to lists because both support __getitem__ -- but I find that similarity shallower than the hash table nature.) In the end I'm +0.5 on | and |=, +0 on + and +=, and -0 on doing nothing.