[Python-ideas] dict.merge(d1, d2, ...) (Counter proposal for PEP 584)

fhsxfhsx fhsxfhsx at 126.com
Tue Mar 5 04:53:09 EST 2019

I agree so much on your opinion that I was just to create a topic about this if you didn't.
I also propose here a small modification to make it more general which adds an argument `how` (name to be discussed), telling how to merge the dicts, as many have pointed out that there could be different ways to merge dicts.
So things would be like

    def addition_merge(key, values, exists):
        :param key: the key to merge
        :param values: values of dicts to merge indexed at `key`
        :param exists: whether each dict contains `key`
        if any(exists):
            return True, sum([value for exist, value in zip(exists, values) if exist])
            return False
    d1.merge(d2, d3, ..., how=addition_merge)

We could even have

    def discard(key, values, exists):
        return not any(exists[1:]), values[0]
    d1.merge(d2, how=discard)

which does the same thing as proposed `d1-d2`.

This would make things like
    d = d1.merge(iter_of_pairs)
d = d1.merge(key=value)
not working, but people could easily wrap a `dict()` over the iterator or key-value stuff and attach no complication.

At 2019-03-05 15:39:40, "INADA Naoki" <songofacandy at gmail.com> wrote:
>I think some people in favor of PEP 584 just want
>single expression for merging dicts without in-place update.
>But I feel it's abuse of operator overload.  I think functions
>and methods are better than operator unless the operator
>has good math metaphor, or very frequently used as concatenate
>This is why function and methods are better:
>* Easy to search.
>* Name can describe it's behavior better than abused operator.
>* Simpler lookup behavior. (e.g. subclass and __iadd__)
>Then, I propose `dict.merge` method.  It is outer-place version
>of `dict.update`, but accepts multiple dicts.  (dict.update()
>can be updated to accept multiple dicts, but it's not out of scope).
>* d = d1.merge(d2)  # d = d1.copy(); d.update(d2)
>* d = d1.merge(d2, d3)  # d = d1.copy(); d.update(d2); d2.update(d3)
>* d = d1.merge(iter_of_pairs)
>* d = d1.merge(key=value)
>## Merits of dict.merge() over operator +
>* Easy to Google (e.g. "python dict merge").
>* Easy to help(dict.merge). (or dict.merge? in IPython)
>* No inefficiency of d1+d2+d3+...+dN, or sum(list_of_many_dicts)
>* Type of returned value is always same to d1.copy().  No issubclass,
>no __iadd__.
>## Why not dict.updated()?
>sorted() is a function so it looks different from L.sort()
>But d.updated() is very similar to d.update() for human eyes.
>## How about d1 - d2?
>If it is really useful, it can be implemented as method too.
>INADA Naoki  <songofacandy at gmail.com>
>Python-ideas mailing list
>Python-ideas at python.org
>Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20190305/517f15be/attachment.html>

More information about the Python-ideas mailing list