[Python-Dev] Re: Sets: elt in dict, lst.include
Tim Peters
tim.one@home.com
Mon, 29 Jan 2001 20:39:17 -0500
[Guido]
> I did a less sophisticated count but come to the same conclusion:
> iterations over items() are (somewhat) more common than over keys(),
> and values() are 1-2 orders of magnitude less common. My numbers:
>
> $ cd python/src/Lib
> $ grep 'for .*items():' *.py | wc -l
> 47
> $ grep 'for .*keys():' *.py | wc -l
> 43
> $ grep 'for .*values():' *.py | wc -l
> 2
I like my larger sample and anal methodology better <wink>. A closer look
showed that it may have been unduly biased by the mass of files in
Lib/encodings/, where
encoding_map = {}
for k,v in decoding_map.items():
encoding_map[v] = k
is at the end of most files (btw, MAL, that's the answer to your question:
people would expect "the same" ordering you expected there, i.e. none in
particular).
> ...
> I don't much value to the readability argument: typically, one will
> write "for key in dict" or "for name in dict" and then it's obvious
> what is meant.
Well, "fiddlesticks" comes to mind <0.9 wink>. If I've got a dict mapping
phone numbers to names, "for name in dict" is dead backwards.
for vevent in keydefs.keys():
for x in self.subdirs.keys():
for name in lsumdict.keys():
for locale in self.descriptions.keys():
for name in attrs.keys():
for func in other.top_level.keys():
for func in target.keys():
for i in u2.keys():
for s in d.keys():
for url in self.bad.keys():
are other cases in the CVS tree where I don't think the name makes it
obvious in the absence of ".keys()".
But I don't personally give any weight to whether people can guess what
something does at first glance. My rule is that it doesn't matter, provided
it's (a) easy to learn; and (especially), (b) hard to *forget* once you've
learned it. A classic example is Python's "points between elements"
treatment of slice indices: few people guess right what that does at first
glance, but once they "get it" they're delighted and rarely mess up again.
And I think this is "like that".
> ...
> But here's my dilemma. "if (k, v) in dict" is clearly useless (nobody
> has even asked me for a has_item() method).
Yup.
> I can live with "x in list" checking the values and "x in dict"
> checking the keys. But I can *not* live with "x in dict" equivalent
> to "dict.has_key(x)" if "for x in dict" would mean
> "for x in dict.items()".
That's why I brought it up -- it's not entirely clear what's to be done
here.
> I also think that defining "x in dict" but not "for x in dict" will
> be confusing.
>
> So we need to think more.
The hoped-for next step indeed.
> How about:
>
> for key in dict: ... # ... over keys
>
> for key:value in dict: ... # ... over items
>
> This is syntactically unambiguous (a colon is currently illegal in
> that position).
Cool! Can we resist adding
if key:value in dict
for "parallelism"? (I know I can ...) 2/3rd of these are marginally more
attractive:
for key: in dict: # over dict.keys()
for :value in dict: # over dict.values()
for : in dict: # a delay loop
> This also suggests:
>
> for index:value in list: ... # ... over zip(range(len(list), list)
>
> while doesn't strike me as bad or ugly, and would fulfill my brother's
> dearest wish.
You mean besides the one that you fry in hell for not adding "for ...
indexing"? Ya, probably.
> (And why didn't we think of this before?)
Best guess: we were focused exclusively on sequences, and a colon just
didn't suggest itself in that context. Second-best guess: having finally
approved one of these gimmicks, you finally got desperate enough to make it
work <wink>.
ponderingly y'rs - tim