[Python-ideas] Adding "+" and "+=" operators to dict

Andrew Barnert abarnert at yahoo.com
Fri Feb 13 04:52:09 CET 2015


On Feb 12, 2015, at 18:45, Steven D'Aprano <steve at pearwood.info> wrote:

> On Thu, Feb 12, 2015 at 07:25:24PM -0700, Eric Snow wrote:
> 
>> Or just make "dict(a, b, c)" work.
> 
> I've come to the same conclusion.
> 
> Pros:
> 
> - No more arguments about which operator is more intuitive, whether 
>  commutativity or associativity is more important, etc. It's just a 
>  short, simple function call.
> 
> - Left-to-right semantics are obvious to anyone who reads left-to-right.
> 
> - No new methods or built-in functions needed.
> 
> - Want a subclass? Just call it instead of dict: MyDict(a, b, c). This 
>  should even work with OrderedDict, modulo the usual 
>  dicts-are-unordered issues.

Except that it doesn't work for OrderedDict. Or UserDict, or blist.sorteddict, or anything else, until those are changed.

> - Like dict.update, this can support iterables of (key,value) 
>  pairs, and optional keyword args.

Which is already true of dict.__init__.
It has the exact same signature--in fact, the example same implementation--as dict.update.

> - dict.update should also be extended to support multiple mappings.
> 
> - No pathologically slow performance from repeated addition.
> 
> - Although the names are slightly different, we have symmetry between 
>  update-in-place using the update method, and copy-and-update using the 
>  dict constructor.
> 
> - Surely this change is minor enough that it doesn't need a PEP? It just
>  needs a patch and approval from a senior developer with commit 
>  privileges.

I'm not sure about this. If you want to change MutableMapping.update too, you'll be potentially breaking all kinds of existing classes that claim to be a MutableMapping and override update with a method with a now-incorrect signature.

> Cons:
> 
> - dict(a,b,c,d) takes 6 characters more to write than a+b+c+d.
> 
> - Doesn't support the less common merge semantics to deal with 
>  duplicate keys, such as adding the values. But then neither would
>  a + operator.
> 
> - The implementation for immutable mappings is not obvious. We can't 
>  literally define the semantics in terms of update, since 
>  Mapping.update doesn't exist:

Of course, since update is a mutating method.

More importantly, neither Mapping nor MutableMapping defines anything at all about its constructor behavior (and neither provides anything as mixin behavior--if you don't define __init__, you get object.__init__, which takes no params and does nothing.

So this doesn't actually change anything at all except dict. All it can do for other mappings is to inspire them to adopt the new 3.5 dict construction behavior.

And the issue with immutable Mapping types isn't that serious--or, rather, it's no more so with this change than it is today. The obvious way to implement MutableMapping.__init__ to be dict-like is to delegate to update (but again, remember that you already have to do so explicitly); there is no obvious way to implement Mapping.__init__, so you have to work something out that makes sense for your specific immutable type. The exact same thing is true after the proposed change.

> py> from collections import Mapping, MutableMapping
> py> Mapping.update
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
> AttributeError: type object 'Mapping' has no attribute 'update'
> py> MutableMapping.update
> <function MutableMapping.update at 0xb7c1353c>


More information about the Python-ideas mailing list