
On Tue, Feb 17, 2015 at 4:38 PM, C Anthony Risinger <anthony@xtfx.me> wrote:
On Tue, Feb 17, 2015 at 4:22 PM, C Anthony Risinger <anthony@xtfx.me> wrote:
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.
Forgot to mention the impl supports arbitrary iterables as the LHS as well, with values simply becoming None. Whether RHS or LHS, a type(fancy_dict) is always returned.
I really really want to reiterate the fact that values are IGNORED... if you just treat a dict like a set with values hanging off the key, the implementation stays perfectly consistent with sets, and does the same thing no matter what it's operating with. Just pretend like the values aren't there and what you get in the end makes a lot of sense.
Trying not to go OT for this thread (or list), run the following on python2 or python3 (http://pastie.org/9958218): import itertools class thing(str): n = itertools.count() def __new__(cls, *args, **kwds): self = super(thing, cls).__new__(cls, *args, **kwds) self.n = next(self.n) print(' LIFE! %s' % self.n) return self def __del__(self): print(' WHYY? %s' % self.n) print('---------------( via constructor )') # bug? literal does something different than constructor? set_of_things = set([thing('hi'), thing('hi'), thing('hi')]) # reset so it's easy to see the difference thing.n = itertools.count() print('---------------( via literal )') # use a different identifier else GC on overwrite unused_set_of_things = {thing('hi'), thing('hi'), thing('hi')} print('---------------( adding another )') set_of_things.add(thing('hi')) print('---------------( done )') you will see something like this: ---------------( via constructor ) LIFE! 0 LIFE! 1 LIFE! 2 WHYY? 2 WHYY? 1 ---------------( via literal ) LIFE! 0 LIFE! 1 LIFE! 2 WHYY? 1 WHYY? 0 ---------------( adding another ) LIFE! 3 WHYY? 3 ---------------( done ) WHYY? 0 WHYY? 2 as shown, adding to a set discards the *new* object, not the old (and as an aside, seems to be a little buggy during construction, else the final 2 would have the same id!)... should this happen? I'm not versed enough in the math behind it to know if it's expected or not, but as it stands, to remain compatible with sets, `d1 | d2` should behave like it does in my code (prefer the first, not the last). I kinda like this, because it makes dict.__or__ a *companion* to .update(), not a replacement (since update prefers the last). -- C Anthony