Why is dictionary.keys() a list and not a set?

Mike Meyer mwm at mired.org
Sat Nov 26 18:07:51 EST 2005


"Martin v. Löwis" <martin at v.loewis.de> writes:
> Mike Meyer wrote:
>>>class mylist1(list):
>>>     def __hash__(self): return 0815
>>>
>>>class mylist2(list):
>>>     def __hash__(self): return id(self)
>>>
>>>In the case of mylist1, everything is ok including semantics, but
>>>performance suffers dramatically. In mylist2, performance is great,
>>>but semantics suffers greatly.
>>>Which of these user-defined types would you call "hashable"?
>> The latter two, as the given __hash__ meets the specifications for
>> __hash__.
> This is not true. The second definition of __hash__ does not meet
> the specifications:

The specification isn't on the __hash__ method, but on objects.
Instances of mylist2 that aren't otherwise tweaked won't meet the
specification.

> http://docs.python.org/ref/customization.html
> "The only required property is that objects which compare equal have the
> same hash value"

That's pretty flaky. The same docs say:

Should return a 32-bit integer usable as a hash value for dictionary
operations.

the dictionary implementation requires that a key's hash value is
immutable

Maybe those are only "recommended" properties, but any class that
doesn't meet them is going to have instances with interesting
behaviors in sets and as dictionary keys.

FWIW, the mutable builtins have __hash__ methods that don't meet that
requirement. Instances of them don't have has values at all.

> However, I can have two instances of mylist2 which compare equal,
> yet have different hash values.

That's a problem with mylist2 instances, and may or may not be a
problem in the mylist2 __hash__ method. You can't tell just by
examining the __hash__ method whether or not it meets this
specification.

        <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list