
Alright, I've tried to gather up all of the feedback and organize it in something approaching the alpha draft of a PEP might look like:: Proposed New Methods on dict ============================ Adds two dicts together, returning a new object with the type of the left hand operand. This would be roughly equivalent to calling: >>> new_dict = old_dict.copy(); >>> new_dict.update(other_dict) Where ``new_dict`` is the same type as ``old_dict``, but possibly not the same as ``other_dict``. __add__ ------- >>> foo = {'a': 1, 'b': 'xyz'} >>> bar = {'a': 5.0, 'c': object()} >>> baz = foo + bar >>> foo {'a': 1, 'b': 'xyz'} >>> bar {'a': 5.0, 'c': object()} >> baz {'a': 5.0, 'b': 'xyz', 'c': object()} __iadd__ -------- >>> foo = {'a': 1, 'b': 'xyz'} >>> bar = {'a': 5.0, 'c': object()} >>> foo += bar >>> foo {'a': 5.0, 'b': 'xyz', 'c': object()} >>> bar {'a': 5.0, 'c': object()} __radd__ -------- The reverse add was mentioned in [2], [5]. I'm not sure I have the following example exactly right, particularly the type. My initial thought is to have it come out as the type of the left hand operand. So, assuming LegacyMap has no ``__add__`` method: >>> foo = LegacyMap{'a': 1, 'b': 'xyz'} >>> bar = dict({'a': 5.0, 'c': object()}) >>> baz = foo + bar # e.g. bar.__radd__(foo) >>> baz {'a': 5.0, 'b': 'xyz', 'c': object()} >>> type(baz) == LegacyMap Considerations ============== Key Collisions -------------- When there is a key collision, handle as currently by ``dict.update()``, namely that the right hand operand "wins". Adding mappings of different types ---------------------------------- Here is what currently happens in a few cases in Python 3.4, given: >>> class A(dict): pass >>> class B(dict): pass >>> foo = A({'a': 1, 'b': 'xyz'}) >>> bar = B({'a': 5.0, 'c': object()}) Currently (this surprised me actually... I guess it gets the parent class?): >>> baz = foo.copy() >>> type(baz) dict Currently: >>> foo.update(bar) >>> foo >>> type(foo) A Idea about '+' adding values ---------------------------- The idea of ``{'x': 1} + {'x': 2} == {'x': 3}`` was mentioned [3], [4] and seems to not have had a lot of support. In particular, this goes against the current usage of the ``dict.update()`` method, where: >>> d = {'x': 1} >>> d.update({'x': 2}) >>> d {'x': 2} '+' vs '|' Operator ------------------- If I was completely uninitiated, I would probably reach for the '+' first, but I don't feel this is the crux of the issue... Backport to PyPI ----------------
And whether it's worth writing a dict subclass that adds this method and putting it on PyPI as a backport (people writing 3.3+ code or 2.7/3.5 code can then just "from dict35 import dict35 as dict", but of course they still won't be able to add two dicts constructed from literals). -- Andrew Barnert [2]
Sure, I'd be willing to do this. References ========== [1] https://mail.python.org/pipermail/python-ideas/2014-July/028440.html [2] https://mail.python.org/pipermail/python-ideas/2015-February/031755.html [3] https://mail.python.org/pipermail/python-ideas/2015-February/031773.html [4] https://mail.python.org/pipermail/python-ideas/2014-July/028425.html Other Discussions ----------------- As best I can, tell from reading through some of these threads there was never really a conclusion, and instead the discussions eventually fizzled out. https://mail.python.org/pipermail/python-ideas/2014-July/028424.html https://mail.python.org/pipermail/python-ideas/2011-December/013227.html https://mail.python.org/pipermail/python-ideas/2013-June/021140.html ~ Ian Lee On Thu, Feb 12, 2015 at 12:59 AM, Florian Bruhin <me@the-compiler.org> wrote:
* M.-A. Lemburg <mal@egenix.com> [2015-02-12 09:51:22 +0100]:
However, I don't really see the point in having an operation that takes two dictionaries, creates a new empty one and updates this with both sides of the operand. It may be theoretically useful, but it results in the same poor performance you have in string concatenation.
In applications, you normally just need the update functionality for dictionaries. If you do need a copy, you can create a copy explicitly - but those cases are usually rare.
So +1 on the '+=' syntax, -1 on '+' for dicts.
I think it'd be rather confusing if += works but + does not.
Regarding duplicate keys, IMHO only two options make sense:
1) Raise an exception 2) The right-hand side overrides keys in the left-hand side.
I think #1 would prevent many useful cases where + could be used instead of .update(), so +1 for #2.
Florian
-- http://www.the-compiler.org | me@the-compiler.org (Mail/XMPP) GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc I love long mails! | http://email.is-not-s.ms/
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/