IndexError and for x in list

Michal Wallace (sabren) sabren at manifestation.com
Thu Apr 13 21:01:22 EDT 2000


Hey all,

Thanks everyone who helped with the indexed dictionary thing..

What I wanted to be able to do was simulate Evilsoft's "Collection"
concept from Visual Basic. Anyway, I have it working (and will release
the code soon as part of a larger project)... But..

I wanted to be able to do this:

idic = IdxDict()

for item in idic:
    print item


which should print the value, whereas:

for key in idic.keys():
    print key

would print the key.

The seqdict class on Parnassus couldn't do this, but the standard
UserList can... I thought this magical behavior might from
__getslice__ or even __len__ or count()... But it doesn't..

for x in list:
   print x


does something like this:


@@@ i = 0
@@@ while true:
@@@     try:
@@@         x = list[i]
@@@         print x
@@@     except IndexError:
@@@         break
@@@     i = i+1


So in order for my object to allow "for x in idic" I needed to
have __getitem__ raise an IndexError, like so:


    def _toStringKey(self, key):
        """Convert numeric keys into string keys. Leaves string keys as is"""
        # handle numeric keys:
        if _isNum(key):
            if not (0 <= key < len(self.idx)):
                ## oddly enough, it is this IndexError here
                ## that allows you to do "for x in myIdxDict:"
                raise IndexError, `key` + " is out of bounds."
            # convert it to a string key
            key = self.idx[key]

        return key


    def __getitem__(self, key):
        key = self._toStringKey(key)
        return self.data[key]



Anyway, aside from informing you all of some Python Trivia :), my
purpose in writing all this is to ask: where is this documented?
The docs for "for" say:

> When the items are exhausted (which is immediately when the sequence
> is empty), the suite in the else clause, if present, is executed, and
> the loop terminates

But it doesn't mention HOW it knows when the list is exhausted.

>From the library reference:

> IndexError
>
> Raised when a sequence subscript is out of range. (Slice indices are
> silently truncated to fall in the allowed range; if an index is not a
> plain integer, TypeError is raised.)

Does "for x in y" have a hidden slice in there?

Basically, I don't want to rely on an undocumented feature that could
go away sometime. Is IndexError the right way to simulate a list?


Cheers,

- Michal
-------------------------------------------------------------------------
http://www.manifestation.com/         http://www.linkwatcher.com/metalog/
-------------------------------------------------------------------------





More information about the Python-list mailing list