[Python-ideas] Adding "+" and "+=" operators to dict

C Anthony Risinger anthony at xtfx.me
Tue Feb 17 23:22:29 CET 2015


On Sun, Feb 15, 2015 at 5:51 PM, Ron Adam <ron3200 at gmail.com> wrote:
>
>
> On 02/15/2015 05:14 PM, Neil Girdhar wrote:
>
>> I'm also +1, I agree with Donald that "|" makes more sense to me than "+"
>> if only for consistency with sets.  In mathematics a mapping is a set of
>> pairs (preimage, postimage), and we are taking the union of these sets.
>>
>
> An option might be to allow a union "|" if both the (key, value) pairs
> that match in each are the same.  Other wise, raise an exception.


I've only loosely followed this thread, so I apologize if examples were
already linked or things already said.

I want to reinforce that set-like operations/parallels are a million times
better than + ... esp. considering dict.viewkeys is pretty much a set.
please please don't use + !!!

Now, a link to an implementation we have used for several years with
success, and the teams here seem to think it makes sense:

https://github.com/xtfxme/xacto/blob/master/xacto/__init__.py#L140

(dont worry about the class decorator/etc, you can just as easily take that
class and subclass dict to get a type supporting all set operations)

The premise taken here is that dicts ARE sets that simply happen to have
values associated with them... hence all operations are against keys ONLY.
The fact that values tag along is irrelevant. I toyed with supporting
values too but it makes things ambiguous (is that a key/val pair or a tuple
key?)

So, given:

>>> d1 = fancy_dict(a=1, b=2, c=3)
>>> d2 = fancy_dict(c=4, d=5, e=6)

The implementation allows you to do such things as:

# union (first key winning here... IIRC this is how sets actually work)
>>> d1 | d2
{'a': 1, 'b': 2, 'c': 3, 'd': 5, 'e': 6}

# intersection (again, first key wins)
>>> d1 & d2
{'c': 3}

# difference (use ANY iterable as a filter!)
>>> d1 - ('a', 'b')
{'c': 3}

# symmetric difference
>>> d1 ^ d2
{'a': 1, 'b': 2, 'd': 5, 'e': 6}

All of the operations support arbitrary iterables as the RHS! This is NICE.

ASIDE: `d1 | d2` is NOT the same as .update() here (though maybe it should
be)... I believe this stems from the fact that (IIRC :) a normal set() WILL
NOT replace an entry it already has with a new one, if they hash() the
same. IOW, a set will prefer the old object to the new one, and since the
values are tied to the keys, the old value persists.

Something to think about.

-- 

C Anthony
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150217/70ad36d4/attachment-0001.html>


More information about the Python-ideas mailing list