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

C Anthony Risinger anthony at xtfx.me
Wed Feb 18 04:30:30 CET 2015


On Tue, Feb 17, 2015 at 4:38 PM, C Anthony Risinger <anthony at xtfx.me> wrote:

> On Tue, Feb 17, 2015 at 4:22 PM, C Anthony Risinger <anthony at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150217/1ee4b3f1/attachment.html>


More information about the Python-ideas mailing list