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

Christoph Zwerschke cito at online.de
Thu Nov 24 17:19:55 CET 2005

Martin v. Löwis schrieb:

> You answer the question whether it would be possible (no, because of
> backwards compatibility); you don't attempt to answer the question
> whether it would be desirable. Why do you think that would be
> a good idea?

It was meant simply as an open question to be discussed here, I did not 
say that I think it would be a good idea. Sometimes it's good to 
question why certain things are set up the way they are.

I considered the question not completely absurd, because if a language 
supports sets and dictionaries, it would be somewhat consequential that 
the keys of a dictionary are a set. (We also discussed "ordered 
dictionaries" here, where it is obvious that the keys are a list.) At 
least from a mathematical/aesthetical view.

If you consider compatibility and usability aspects, making them sets 
would probably not be a good idea.

> If you want the set of keys of a dictionary d, then do set(d):
>  >>> d={1:2,3:4}
>  >>> set(d)
> set([1, 3])

I know. But this does not answer the question: If the keys *are* already 
a set according to their semantics, why aren't they returned as a set 
from the beginning?

Better answers:

- Compatibility issues, particularly the keys()/values() match hattrick
- Because lists are still more native/pythonic objects than sets

> As Mike Meyer explains, the same is meaningless for .values():
> they might not be unique. For .items(), conversion into a set
> does would appear to be meaningful, but doesn't actually work:
> if the values contain unhashable objects, the set of tuples
> cannot be constructed (as set members must be immutable).

I would not say that a values() set would be meaningless; it is an 
interesting object in itself. It would however lose the information 
about the "frequency" of the values.

But your second objection is a valid one. So I can add to the list of 
reasons why sets are not used for values() and items():

- Because sets can only contain immutable values

This, of course, in turn raises the question ;-) Would it be desirable 
to have an additional, more general set datatype that can contain 
mutable objects? I know about the perfomance drawbacks. And I think I 
know the answer: It would not make much sense, since the implementation 
would be actually not different from a list. So you could take a list 
anyway. Which gives the answer why values() and items() return a list.

Probably the only use of such a general set type would be that it could 
be considered as an abstract supertype for list and value. And in cases 
where the order does not matter, this could be made more clear by using 
sets. (Similar as the reason why you use False and True when you could 
use 0 and 1 instead.)

-- Christoph

More information about the Python-list mailing list