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

Mike Meyer mwm at mired.org
Fri Nov 25 22:46:27 CET 2005

Christoph Zwerschke <cito at online.de> writes:
> Mike Meyer schrieb:
>> Ok, how about this for dictionaries/sets:
>> Any hashable object can be used as a dictionary key (set
>> member). Immutable
>> objects, except for tuples that contain a non-hashable object, are
>> hashable. Python classes are normally hashable(1).
> I would be even more simple here, like that:
> The keys can be arbitrary immutable objects. Thus lists, sets or
> dictionaries are not allowed as keys. Tuples are allowed if they do
> not directly or indirectly contain mutable objects. More exactly, the
> keys are required to be hashable (1).
> And then go on and define "hashable" in the footnot.
> I think that is easy and understandable and covers the basic cases.

You're shifting the emphasis from hashable back to mutable, which is
the problem that I'm trying to fix. The mutability - or immutability -
of an object is irrelevant to the question of whether or not they can
be a dictionary key/set element. The critical property is that they
are hashable. *Most* immutable builtin types are hashable, and no
builtin mutable types are hashable, which deserves a mention. Once you
get away from the builtins, mutability simply stops mattering. Giving
mutability top billing is simply wrong.

>> And the footnote is:
>> Instances of Python classes are hashable if they define a __hash__
>> method, or if they don't define either __cmp__ or __eq__.
> I think that's not exact enough. For instance, ordinary lists also
> define a __hash__ method but are not hashable since that method just
> raises an exception.

Ordinary lists aren't Python classes.

> Also, as Martin pointed out, if both is there
> (__hash__ and __cmp__/__eq__) you would also require of a "proper"
> __hash__ method that equal objects hash the same. Otherwise, semantics
> would suffer, you could have dicts with non-unique keys (i.e. keys
> which are only distinct as objects, but not different as values).

Um, actually, I pointed that out (possibly as well), and included it
in one of the earlier versions. I was contemplating moving it
elsewhere, and accidently left it out. It certainly deserves mention
somewhere; I'm just not sure that here is the right place. Along with
__hash__ seems more appropriate.

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