Peter Maas wrote:
Steven Bethard schrieb:

If lists were hashable, new programmers to Python would almost certainly make mistakes like:

py> d = {[1, 2, 3]: 'abc'}


 > The coder here almost certainly *doesn't* want that list to be compared
 > by id.  The only way to get a binding for that list would be using the
 > dict's keys or __iter__ methods.

That's what I meant when I said that for lists id() doesn't make sense
as hash because of the list literals.

As Andrew Koenig said, this has less to do with the fact that lists can be written with list literals, and more to do with the fact that lists are mutable containers. Because they're containers, it makes sense to compare them by comparing their contents. But because they're mutable, a hash value based on their contents cannot be guaranteed to be stable. Hashing them by their id would force the user to mentally switch between thinking of lists as containers and thinking of lists as non-container objects.


Note that there is no such thing as a 'set literal', yet sets exhibit the same behavior:

py> d = {set([1, 2]):100, set('a b'.split()):200}
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
TypeError: set objects are unhashable

Sets are containers, and thus should be comparable by their contents. But sets are mutable, so they cannot be hashed by their contents. Rather than force the user to do the mental mind-switch between container and non-container, Python opts to make sets unhashable.

Note that, much as tuples are to lists, frozensets are to sets:

py> d = {frozenset([1, 2]):100, frozenset('a b'.split()):200}
py> d[frozenset([2, 1])]
100
py> d[frozenset(['b', 'a'])]
200

Because frozensets are immutable, they can not only be compared by their contents, but they can be hashed by these contents as well.

Steve
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to