<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Feb 15, 2015 at 5:51 PM, Ron Adam <span dir="ltr"><<a href="mailto:ron3200@gmail.com" target="_blank">ron3200@gmail.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<br>
On 02/15/2015 05:14 PM, Neil Girdhar wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I'm also +1, I agree with Donald that "|" makes more sense to me than "+"<br>
if only for consistency with sets.  In mathematics a mapping is a set of<br>
pairs (preimage, postimage), and we are taking the union of these sets.<br>
</blockquote>
<br></span>
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.</blockquote><div><br></div><div>I've only loosely followed this thread, so I apologize if examples were already linked or things already said.</div><div><br></div><div>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 + !!!</div><div><br></div><div>Now, a link to an implementation we have used for several years with success, and the teams here seem to think it makes sense:</div><div><br></div><div><a href="https://github.com/xtfxme/xacto/blob/master/xacto/__init__.py#L140">https://github.com/xtfxme/xacto/blob/master/xacto/__init__.py#L140</a><br></div><div><br></div><div>(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)</div><div><br></div><div>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?)</div><div><br></div><div>So, given:</div><div><br></div><div>>>> d1 = fancy_dict(a=1, b=2, c=3)<br></div><div>>>> d2 = fancy_dict(c=4, d=5, e=6)<br></div><div><br></div><div>The implementation allows you to do such things as:</div><div><br></div><div># union (first key winning here... IIRC this is how sets actually work)</div><div>>>> d1 | d2</div><div>{'a': 1, 'b': 2, 'c': 3, 'd': 5, 'e': 6}<br></div><div><br></div><div># intersection (again, first key wins)</div><div>>>> d1 & d2<br></div><div>{'c': 3}<br></div><div> </div><div># difference (use ANY iterable as a filter!)</div><div>>>> d1 - ('a', 'b')</div><div>{'c': 3}<br></div><div><br></div><div># symmetric difference</div><div>>>> d1 ^ d2<br></div><div>{'a': 1, 'b': 2, 'd': 5, 'e': 6}<br></div><div><br></div><div>All of the operations support arbitrary iterables as the RHS! This is NICE.</div><div><br></div><div>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.</div><div><br></div><div>Something to think about.</div><div><br></div></div>-- <br><div class="gmail_signature"><br>C Anthony</div>
</div></div>