"Tim Peters" <tim@zope.com> writes: > [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? The source, Luke. But sadly I was just mis-reading the wrong branch of the if clause. It's hard to understand why that Py_DECREF is needed, but it was just the distraction my hopeful brain needed to tell me it would work ;-( static void insertdict(register dictobject *mp, PyObject *key, long hash, PyObject *value) { PyObject *old_value; register dictentry *ep; typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); assert(mp->ma_lookup != NULL); ep = mp->ma_lookup(mp, key, hash); if (ep->me_value != NULL) { old_value = ep->me_value; ep->me_value = value; Py_DECREF(old_value); /* which **CAN** re-enter */ Py_DECREF(key); } else { if (ep->me_key == NULL) mp->ma_fill++; else Py_DECREF(ep->me_key); ^^^^^^^^^^^^^^^^^^^^^ ep->me_key = key; -- Dave Abrahams Boost Consulting www.boost-consulting.com
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4