"[EMAIL PROTECTED]" <[EMAIL PROTECTED]> writes: >> Not all tuples can be elements of a set. Elements of a set have to be >> hashable. Tuples compute their hash by hashing their contents. If >> their contents aren't hashable, the tuple isn't hashable, and hence >> can't be an element of a set. If the values in the dictionary aren't >> hashable, then the tuples returned by items() won't be hashable >> either, and hence can't be elements of a set. >> > A related issue, from the doc : > > Set elements are like dictionary keys; they need to define both > __hash__ and __eq__ methods.
This is wrong. The objects must have a hash value to be used as a set element or a dictionary key. Objects without a __hash__ use their id as a hash value if they don't define their own comparisons. This makes sense, because objects that don't define their own comparisons use id testing for equality testing. The __eq__ comment is even worse - __eq__ is unused on set elements or dictionary keys. However, the *semantics* of sets and keys are such that if hash(x) == hash(y), then x == y should also be true. If that's false, then lots of the statements about dictionaries and sets are going to be wrong. The behavior of tuples is a different issue: hashing a non-hashable object raises a TypeError. So does hashing a tuple that contains a non-hashable object. This doesn't matter for most containers: lists aren't hashable in any case; strings, unicode strings and xrange's, as they contain only hashable objects. Buffers are poorly documented. The dictionary doc comment is closer to right: A dictionary's keys are almost arbitrary values. Only values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys. Proposed new wording, for both places: A dictionaries keys (set element) can be any hashable value. Immutable objects are hashable, except that a tuple containing a non-hashable object isn't hashable. Mutable objects are hashable if they define __hash__ or if they don't define comparison. A class or type that defines both comparison and __hash__ should define them so that two objects that have the same hash compare equal, otherwise using them as dictionary keys (set elements) will not have the expected behavior. What do the rest of you think? <mike -- Mike Meyer <[EMAIL PROTECTED]> http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list