[Python-ideas] PEP: Dict addition and subtraction

Michael Lee michael.lee.0x2a at gmail.com
Wed Mar 6 13:22:54 EST 2019

> If we use this "literally concat" metaphor, I still think set should have
> `+` as alias to `|` for consistency.

I agree.

I think "|" keeps commutativity only because it's minor than `+`.

I suppose that's true, fair point.

I guess I would be ok with | no longer always implying commutativity if we
were repurposing it for some radically different purpose. But dicts and
sets are similar enough that I think having them both use similar but
ultimately different definitions of "|" is going to have non-zero cost,
especially when reading or modifying future code that makes heavy use of
both data structures.

Maybe that cost is worth it. I'm personally not convinced, but I do think
it should be taken into account..

Hmm.  The PEP proposed dict - dict, which is similar to set - set
> (difference).

Now that you point it out, I think I also dislike `d1 - d2` for the same
reasons I listed earlier: it's not consistent with set semantics. One other
objection I overlooked is that the PEP currently requires both operands to
be dicts when doing "d1 - d2" . So doing {"a": 1, "b": 2, "c": 3} - ["a",
"b"] is currently disallowed (though doing d1 -= ["a", "b"] is apparently

I can sympathize: allowing "d1 - some_iter" feels a little too magical to
me. But it's unfortunately restrictive -- I suspect removing keys stored
within a list or something would be just as common of a use-case if not
more so then removing keys stored in another dict.

I propose that we instead add methods like "d1.without_keys(...)" and
"d1.remove_keys(...)" that can accept any iterable of keys. These two
methods would replace "d1.__sub__(...)" and "d1.__isub__(...)"
respectively. The exact method names and semantics could probably do with a
little more bikeshedding, but I think this idea would remove a false
symmetry between "d1 + d2" and "d1 - d2" that doesn't actually really exist
while being more broadly useful.

Or I guess we could just remove that restriction: "it feels too magical"
isn't a great objection on my part. Either way, that part of the PEP could
use some more refinement, I think.

-- Michael

On Wed, Mar 6, 2019 at 8:29 AM Inada Naoki <songofacandy at gmail.com> wrote:

> On Wed, Mar 6, 2019 at 10:59 PM Michael Lee <michael.lee.0x2a at gmail.com>
> wrote:
> >
> > I think the behavior proposed in the PEP makes sense whether you think
> of "+" as meaning "concatenation" or "merging".
> >
> > If your instinct is to assume "+" means "concatenation", then it would
> be natural to assume that {"a": 1, "b": 2} + {"c": 3, "b": 4} would be
> identical to {"a": 1, "b": 2, "c": 3, "b": 4} -- literally concat the
> key-value pairs into a new dict.
> >
> Nice explanation.  You reduced my opposite to `+` by "literally concat".
> Better example, {"a": 1, "b": 2} + {"c": 4, "b": 3} == {"a": 1, "b":
> 2, "c": 4, "b": 3} == {"a": 1, "b": 3, "c": 4}
> On the other hand, union of set is also "literally concat".  If we use
> this "literally concat" metaphor,
> I still think set should have `+` as alias to `|` for consistency.
> >
> > Using "|" would also violate an important existing property of unions:
> the invariant "d1 | d2 == d2 | d1" is no longer true. As far as I'm aware,
> the union operation is always taken to be commutative in math, and so I
> think it's important that we preserve that property in Python. At the very
> least, I think it's far more important to preserve commutativity of unions
> then it is to preserve some of the invariants I've seen proposed above,
> like "len(d1 + d2) == len(d1) + len(d2)".
> >
> I think both rule are "rather a coincidence than a conscious decision".
> I think "|" keeps commutativity only because it's minor than `+`.  Easy
> operator
> is abused easily more than minor operator.
> And I think every "coincidence" rules are important.  They makes
> understanding Python easy.
> Every people "discover" rules and consistency while learning language.
> This is a matter of balance.  There are no right answer.  Someone
> *feel* rule A is important than B.
> Someone feel opposite.
> > But I do know that I'm a strong -1 on adding set operations to dicts:
> it's not possible to preserve the existing semantics of union (and
> intersection) with dict and  think expressions like "d1 | d2" and "d1 & d2"
> would just be confusing and misleading to encounter in the wild.
> Hmm.  The PEP proposed dict - dict, which is similar to set - set
> (difference).
> To me, {"a": 1, "b": 2} - {"b": 3} = {"a": 1} is confusing than {"a":
> 1, "b": 2} - {"b"} = {"a": 1}.
> So I think borrow some semantics from set is good idea.
> Both of `dict - set` and `dict & set` makes sense to me.
> * `dict - set` can be used to remove private keys by "blacklist".
> * `dict & set` can be used to choose public keys by "whiltelist".
> --
> Inada Naoki  <songofacandy at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20190306/fba8be51/attachment-0001.html>

More information about the Python-ideas mailing list