[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