len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the + operator is nonsense.len(dict1 + dict2) cannot even be computed by any expression involving +. Using len() to test the semantics of the operation is not arbitrary; the fact that the sizes do not add is a defining quality of a merge. This is a merge, not an addition. The proper analogy is to sets, not lists.The operators should be |, &, and -, exactly as for sets, and the behaviour defined with just three rules:1. The keys of dict1 [op] dict2 are the elements of dict1.keys() [op] dict2.keys().2. The values of dict2 take priority over the values of dict1.3. When either operand is a set, it is treated as a dict whose values are None.This yields many useful operations and, most importantly, is simple to explain. "sets and dicts can |, &, -" takes up less space in your brain than "sets can |, &, - but dicts can only + and -, where dict + is like set |".merge and update some items:{'a': 1, 'b': 2} | {'b': 3, 'c': 4} => {'a': 1, 'b': 3, 'c': 4}pick some items:{'a': 1, 'b': 2} & {'b': 3, 'c': 4} => {'b': 3}remove some items:{'a': 1, 'b': 2} - {'b': 3, 'c': 4} => {'a': 1}reset values of some keys:{'a': 1, 'b': 2} | {'b', 'c'} => {'a': 1, 'b': None, 'c': None}ensure certain keys are present:{'b', 'c'} | {'a': 1, 'b': 2} => {'a': 1, 'b': 2, 'c': None}pick some items:{'b', 'c'} | {'a': 1, 'b': 2} => {'b': 2}remove some items:{'a': 1, 'b': 2} - {'b', 'c'} => {'a': 1}_______________________________________________On Wed, Mar 6, 2019 at 1:51 AM Rémi Lapeyre <remi.lapeyre@henki.fr> wrote:Le 6 mars 2019 à 10:26:15, Brice Parent
(contact@brice.xyz(mailto:contact@brice.xyz)) a écrit:
>
> Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > Steven D'Aprano wrote:
> >> The question is, is [recursive merge] behaviour useful enough and
> > > common enough to be built into dict itself?
> >
> > I think not. It seems like just one possible way of merging
> > values out of many. I think it would be better to provide
> > a merge function or method that lets you specify a function
> > for merging values.
> >
> That's what this conversation led me to. I'm not against the addition
> for the most general usage (and current PEP's describes the behaviour I
> would expect before reading the doc), but for all other more specific
> usages, where we intend any special or not-so-common behaviour, I'd go
> with modifying Dict.update like this:
>
> foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> keyword I used
Le 6 mars 2019 à 10:26:15, Brice Parent
(contact@brice.xyz(mailto:contact@brice.xyz)) a écrit:
>
> Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > Steven D'Aprano wrote:
> >> The question is, is [recursive merge] behaviour useful enough and
> > > common enough to be built into dict itself?
> >
> > I think not. It seems like just one possible way of merging
> > values out of many. I think it would be better to provide
> > a merge function or method that lets you specify a function
> > for merging values.
> >
> That's what this conversation led me to. I'm not against the addition
> for the most general usage (and current PEP's describes the behaviour I
> would expect before reading the doc), but for all other more specific
> usages, where we intend any special or not-so-common behaviour, I'd go
> with modifying Dict.update like this:
>
> foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> keyword I used
This won’t be possible update() already takes keyword arguments:
>>> foo = {}
>>> bar = {'a': 1}
>>> foo.update(bar, on_collision=lambda e: e)
>>> foo
{'a': 1, 'on_collision': <function <lambda> at 0x10b8df598>}
> `updator` being a simple function like this one:
>
> def updator(updated, updator, key) -> Any:
> if key == "related":
> return updated[key].update(updator[key])
>
> if key == "tags":
> return updated[key] + updator[key]
>
> if key in ["a", "b", "c"]: # Those
> return updated[key]
>
> return updator[key]
>
> There's nothing here that couldn't be made today by using a custom
> update function, but leaving the burden of checking for values that are
> in both and actually inserting the new values to Python's language, and
> keeping on our side only the parts that are specific to our use case,
> makes in my opinion the code more readable, with fewer possible bugs and
> possibly better optimization.
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/