Can't get around "IndexError: list index out of range"

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Oct 7 20:41:50 EDT 2006


On Sat, 07 Oct 2006 10:26:22 -0700, MonkeeSage wrote:

> 
> 
> On Oct 7, 3:27 am, Gabriel Genellina <gagsl... at yahoo.com.ar> wrote:
>> The meaning comes from the most common usage.
> 
> I wasn't suggesting that the "in" keyword have a different sematic for
> sequence types. I was just saying that regarding the question whether
> there is anything similar to "dict.has_key / k in dict" for lists, the
> "in" keyword is not semantically analogous.

Are you just making a philosophical point? In which case I agree: *if* you
make the analogy "a dictionary key is analogous to a sequence index",
*then* the operation of "in" isn't semantically analogous between mappings
and sequences. But why should it be?

In both mappings and sequences, "in" tests for membership. But *what* it
tests for membership is different. There's no shame there.


>> Because it's not needed at all: valid sequence indexes are *exactly*
>> range(len(seq)). This is the basic point of being a sequence: when
>> indexes are not contiguous, in fact you have a mapping, not a sequence.
> 
> True. But valid dictionary keys are exactly d.keys(). The has_key
> method is just sugar.


A little bit of history might be useful here. Originally, if you wanted to
test for key membership with a dict, you had three choices:

(1) Easier To Ask Forgiveness Than Permission:

try:
    mapping[key]
except KeyError:
    print "Oops, that's not a key!"


(2) mapping.has_key(key), which inspected the dict's internals to
determine whether key was valid or not.

(3) Build a list of keys, then test whether the key was in the list:

key in mappings.keys()


Obviously all three methods had their disadvantages. The first required
catching an exception, which is expensive, and is less than clear. The
second is a magic method that needs to be remembered by the developer,
and breaks the equivalence of mappings and sequences. The third means
building, and throwing away, a temporary list of keys.

But after types and classes were unified, dicts grew a __contains__
method for subclassing. If you want syntactic sugar, "x in obj" is
"just" syntactic sugar for obj.__contains__(x) (but note the scare quotes
around just: one person's syntactic sugar is another person's essential
syntactic feature).



-- 
Steven.




More information about the Python-list mailing list