On Tue, Dec 3, 2019 at 2:02 AM Serhiy Storchaka <storchaka@gmail.com> wrote:
I general, I am against this proposition. It makes the language more complex without adding any benefit. There are already many ways of merging dicts, including the expression form. It conflicts with Counter. It can make the code more errorprone because + or | for dicts will no longer fail immediately.
But if this proposition be accepted, I will try to make it as consistent and harmless to the language as possible.
02.12.19 21:54, Guido van Rossum пише:
## Should the operators be + and +=, or | and |= ?
I argued for | and |= as lesser evil. But there may be a problem. Dict and dict keys view are interchangeable in the context of some set operations: "in" checks for existence of the key and iterating yields keys. Currently both `dictkeys | dict` and `dict | dictkeys` return the same, the set containing the union of keys.
Hm, I didn't know this. But it shouldn't change. This is a special case in keys(), it seems -- set | dict and dict | set fail. The special case can continue to return the same outcome.
{1: 2}.keys() | {3} {1, 3} {3} | {1: 2}.keys() {1, 3}
Your example uses sets -- did you mean {3: 4} instead of {3}?
What it will return if implement | for dicts? It should be mentioned in the PEP. It should be tested with a preliminary implementation what behavior is possible and more natural.
Again, Steven, please take note.
## What about performance?
It should be mentioned in the PEP that `dict1 | dict2 | dict3` is less efficient than `{**dict1, **dict2, **dict3}`.
Ditto. (I think this is a much less common use case -- more common is a variable number of dicts, which I would solve with a loop over update() or over |=.)
## Other objections
The principal question about the result type was not mentioned above. `dict | dict` should return an exact dict for dict subclasses for the same reasons as not including __or__ in the Mapping API. We cannot guarantee the signature and the behavior of the constructor and therefore we have no way to create a copy as an instance of general dict subclass. This is why `dict.copy()` returns an exact dict. This is why `list + list`, `tuple + tuple`, `str + str`, `set | set`, `frozenset | frozenset`, etc, etc return an instance of the base class. This is why all binary operators for numbers (like `int + int`, `float * float`) return an instance of the base class. Making `dict | dict` returning an instance of a dict subclass will be an exception to the rule.
Also an important detail, and again I hope that Steven adds this to the PEP. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>