How to stop iteration with __iter__() ?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Wed Aug 20 09:43:49 EDT 2008


On Wed, 20 Aug 2008 06:16:17 -0700, MRAB wrote:

> So it's defined behaviour that an exhausted iterable will always raise
> StopIteration no matter how many times it's asked for the next value?

Be careful -- an iterable is not the same as an iterator.

Iterables are anything that you can iterate over. This includes strings, 
lists, tuples, dicts and, yes, iterators.

But not all iterables are iterators. Only iterators raise StopIteration. 
The defined behaviour of iterators is that once exhausted, they will 
always raise StopIteration.

Basically, Python will do the right thing in a for loop regardless of 
whether you pass an iterator or some other type of iterable. You don't 
have to worry about the mechanics of it, but if you care, it works 
something like this:

When Python executes a for-loop:

for item in obj:
    BLOCK

it does something kind of like this:


if hasattr(obj, "next"):
    # Looks like an iterator.
    while True:
        try:
            item = obj.next()
        except StopIteration:
            break
        execute BLOCK
elif hasattr(obj, "__getitem__"):
    # Looks like a string, or list, or similar.
    i = 0
    while True:
        try:
            item = obj[i]
        except IndexError:
            break
        execute BLOCK
        i += 1
else:
    raise TypeError('object not iterable')



-- 
Steven



More information about the Python-list mailing list