[Python-Dev] Mundane dict __setitem__...

Tim Peters tim@zope.com
Tue, 3 Jun 2003 11:06:42 -0400


[David Abrahams]
>> I am about to write some code which relies on the following:
>>
>>     x = (1,2,3)
>>     y = (1,2,3)
>>     d = {}
>>     d[x] = 1
>>     d[y] = 1
>>     assert d.keys()[0] is y
>>
>> In other words, when you do d[k] = v it replaces both v *and* k in
>> the dict.  I couldn't find it documented anywhere but the source.  I
>> submitted a doc patch which enshrines that behavior, but since Guido
>> doesn't always know what's in the doc I wanted to make sure it was
>> considered reasonable.
>>
>> Anyone want to tell me it's a bad idea?  It seems like the more
>> useful of the two possible behaviors to me.

[Samuele Pedroni]
> that's not the case with Jython, i.e. the assert will fail in Jython.

It probably fails in CPython too:

>>> x = (1, 2, 3)
>>> y = (1, 2, 3)
>>> d = {x: 1}
>>> d[y] = 1
>>> map(id, d.keys())  # shows that x is still a key
[7872560]
>>> id(x), id(y)
(7872560, 8348336)
>>>

Dave, what made you think x gets replaced?

> Dicts are equality not identity dicts so both behavior, as I see it,
> are fine. In the end what happens with the fragment is unspecified.

Well, it is specified that after

    d[k] = v

then

    d[k'] == v'

for any pair (k', v') such that

    assert k == k' and v == v'

holds, and k' is hashable, and type(k) and type(k') meet the requirement
that objects that compare equal also have equal hash codes.  Or at least
that's virtually specified <wink>.