[Python-Dev] re: for in dict (user expectation poll)
Ka-Ping Yee
ping@lfw.org
Tue, 6 Feb 2001 03:32:27 -0800 (PST)
On Mon, 5 Feb 2001, Guido van Rossum wrote:
>
> [Ping]
> > I think your survey shows that the PEP made the right choices.
> > That is, it supports the position that if 'for key:value' is
> > supported, then 'for key:' and 'for :value' should be supported,
> > but 'for x in dict:' should not. It also shows that 'for index:'
> > should be supported on sequences, which the PEP suggests.
>
> But then we should review the wisdom of using "if x in dict" as a
> shortcut for "if dict.has_key(x)" again. Everything is tied together!
Okay. Here's the philosophy; i'll describe my thinking more
explicitly.
Presumably we can all agree that if you ask to iterate over things
"in" a sequence, you clearly want the items in the sequence, not
their integer indices. You care about the data *you* put in the
container. In the case of a list, you care about the items more
than these additional integers that got supplied as a result of
using an ordered data structure. So the meaning of
for thing in sequence:
is pretty clear.
The meaning of
for thing in mapping:
is less clear, since both the keys and the values are interesting
data to you. If i ask you to "get me all the things in the
dictionary", it's not so obvious whether you should get me a list
of just the words, just the definitions, or both (probably both,
i suppose).
But, if i ask you to "find 'aardvark' in the dictionary" or i ask
you "is 'aardvark' in the dictionary?" it's completely obvious
what i mean. "if key in dict:" makes sense both by this analogy
to common use, and by an argument from efficiency (even the most
rudimentary understanding of how a dictionary works is enough to
see why we look up keys rather than values). In fact, we *call*
it a dictionary because it works like a real dictionary: it's
designed for data lookup in one direction, from key to value.
"if thing in container" is about *finding* something specific.
"for thing in container" is about getting everything out.
Now, i know this isn't the strongest argument in the world, and
i can see the potential objection that the two aren't consistent,
but i think it's a very small thing that only has to be
explained once, and then is easy to remember and understand.
I consider this little difference less of an issue than the
hasattr/has_key inconsistency that it will largely replace.
We make expectations clear:
for item in sequence:
continues to mean, "i expect a sequence", exactly as it does
now. When not given a sequence, the 'for' loop complains.
Nothing could break, as the interpretation of this loop is
unchanged.
These three forms:
for k:v in anycontainer:
for k: in anycontainer:
for :v in anycontainer:
mean: "i am expecting any indexable thing, where ctr[k] = v".
As far as the syntax goes, that's all there is to it:
for item in sequence: # only on sequences
for k:v in anycontainer: # get keys and values on anything
for k: in anycontainer: # just keys
for :v in anycontainer: # just values
-- ?!ng
"There's no point in being grown up if you can't be childish sometimes."
-- Dr. Who