That does put a kink in my argument that Python is simply refusing to guess in the face of ambiguity. I'm still convinced that disallowing lists as dict keys is a good thing, but it leaves me unable to explain why __hash__()-less user-defined classes (which are mutable almost by definition) are allowed.
Because the default definition of equality is *also* based on object id. Since the hash and equality are based on the same thing, such classes can be safely used as dictionary keys.
As soon as you define __cmp__ or __eq__ Python does *not* supply a default implementation of __hash__ - since it can no longer assume that an identity based hash will give a correct answer.
Py> class Hashable: pass ... Py> hash(Hashable()) 10331280 Py> d = {Hashable(): "Hi"} Py> d {<__main__.Hashable instance at 0x009DA490>: 'Hi'} Py> class NotHashable: ... def __cmp__(self, other): ... return 0 ... Py> hash(NotHashable()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unhashable instance Py> d = {NotHashable(): "Hi"} Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: unhashable instance
Although, it looks like new-style classes currently don't apply this rule - you get the default hash implementation from object no matter what:
Py> class NotHashable(object): ... def __cmp__(self, other): ... return 0 ... Py> hash(NotHashable()) 10297264 Py> d = {NotHashable(): "Hi"} Py> d {<__main__.NotHashable object at 0x009D1FF0>: 'Hi'}
That may be a bug rather than a feature :)
Cheers, Nick.
-- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.skystorm.net -- http://mail.python.org/mailman/listinfo/python-list