[Python-ideas] PEP: Dict addition and subtraction
David Shawley
daveshawley at gmail.com
Tue Mar 5 08:11:29 EST 2019
On Mar 4, 2019, at 4:51 AM, Stefan Behnel <stefan_ml at behnel.de> wrote:
>
> I think the main intentions is to close a gap in the language.
>
> [1,2,3] + [4,5,6]
>
> works for lists and tuples,
>
> {1,2,3} | {4,5,6}
>
> works for sets, but joining two dicts isn't simply
>
> {1:2, 3:4} + {5:6}
>
> but requires either some obscure syntax or a statement instead of a simple
> expression.
>
> The proposal is to enable the obvious syntax for something that should be
> obvious.
I would challenge that this dictionary merging is something that is
obvious. The existing sequences are simple collections of values
where a dictionary is a mapping of values. The difference between
the two is akin to the difference between a mathematical array or
set and a unary mapping function. There is a clear and obvious way to
combine arrays and sets -- concatenation for arrays and union for sets.
Combining mapping functions is less than obvious.
"Putting Metaclasses to Work" (ISBN-13 978-0201433050) presents a more
mathematical view of programming language types that includes two
distinct operations for combining dictionaries -- merge and recursive
merge.
For two input dictionaries D1 & D2 and the output dictionary O
D1 merge D2
O is D1 with the of those keys of D2 that do not have keys in D1
D1 recursive-merge D2
For all keys k, O[k] = D1[k] recursive merge D2[k] if both D1[k]
and D2[k] are dictionaries, otherwise O[k] = (D1 merge D2)[k].
Note that neither of the cases is the same as:
>>> O = D1.copy()
>>> O.update(D2)
So that gives us three different ways to combine dictionaries that are
each sensible. The following example uses dictionaries from "Putting
Metaclasses to Work":
>>> d1 = {
... 'title': 'Structured Programming',
... 'authors': 'Dahl, Dijkstra, and Hoare',
... 'locations': {
... 'Dahl': 'University of Oslo',
... 'Dijkstra': 'University of Texas',
... 'Hoare': 'Oxford University',
... },
... }
>>>
>>> d2 = {
... 'publisher': 'Academic Press',
... 'locations': {
... 'North America': 'New York',
... 'Europe': 'London',
... },
... }
>>>
>>> o = d1.copy()
>>> o.update(d2)
>>> o
{'publisher': 'Academic Press',
'title': 'Structured Programming',
'locations': {'North America': 'New York', 'Europe': 'London'},
'authors': 'Dahl, Dijkstra, and Hoare'}
>>>
>>> merge(d1, d2)
{'publisher': 'Academic Press',
'title': 'Structured Programming',
'locations': {'Dijkstra': 'University of Texas',
'Hoare': 'Oxford University',
'Dahl': 'University of Oslo'},
'authors': 'Dahl, Dijkstra, and Hoare'}
>>>
>>> recursive_merge(d1, d2)
{'publisher': 'Academic Press',
'title': 'Structured Programming',
'locations': {'North America': 'New York',
'Europe': 'London',
'Dijkstra': 'University of Texas',
'Hoare': 'Oxford University',
'Dahl': 'University of Oslo'},
'authors': 'Dahl, Dijkstra, and Hoare'}
>>>
https://repl.it/@dave_shawley/PuttingMetaclassesToWork <https://repl.it/@dave_shawley/PuttingMetaclassesToWork>
IMO, having more than one obvious outcome means that we should refuse
the temptation to guess. If we do, then the result is only obvious
to a subset of users and will be a surprise to the others.
It's also useful to note that I am having trouble coming up with
another programming language that supports a "+" operator for map types.
Does anyone have an example of another programming language that
allows for addition of dictionaries/mappings?
If so, what is the behavior there?
- dave
--
Any linter or project that treats PEP 8 as mandatory has *already*
failed, as PEP 8 itself states that the rules can be broken as needed. - Paul Moore.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20190305/5d4bf885/attachment-0001.html>
More information about the Python-ideas
mailing list