Iterating over multiple lists (a newbie question)

Alex Martelli aleaxit at yahoo.com
Sat Jan 6 14:20:37 EST 2001


"Greg Jorgensen" <gregj at pobox.com> wrote in message
news:QkD56.235798$U46.7334091 at news1.sttls1.wa.home.com...
    [snip]
> Someone correct me if I'm wrong, but Python only looks like it has list
> iterators. Based on my understanding of the methods supported by sequence
> types, the statement
>
>     for item in list:
>         ...
>
> is equivalent to
>
>     for i in range(len(list)):
>         item = list[i]
>         ...

Almost, not quite.  It's closer to:
    i = 0
    while 1:
        try:
            item = list[i]
        except IndexError:
            break
        i += 1
        # the rest goes here

I.e., the sequence being iterated upon with for does not have to
define a 'length': rather, it lets the iteration know that it's done
by raising an IndexError exception.

This is somewhat meaningful, in that it lets you implement a
sequence 'lazily' pretty easily: you don't have to know in advance
how many items you'll have -- just to be able to fetch them in
order, 0-th upwards, and know when you have no more to give
(then raise IndexError).

E.g.:

>>> class Numbers:
...   def __getitem__(self, i):
...     return i
...
>>> for x in Numbers():
...     print x,
...     if x>10: break
...
0 1 2 3 4 5 6 7 8 9 10 11
>>>

A 'for' iterating over an instance of Numbers had better have its
own terminating-break, of course -- "for x in Numbers():" works
much like a "while 1:" that knows which time around this is.

The sequence-iteration protocol is also used by the zip builtin
function, which terminates with the _shortest_ sequence it's
given:

>>> a=zip("ciao",Numbers())
>>> a
[('c', 0), ('i', 1), ('a', 2), ('o', 3)]
>>>

and THIS can be somewhat handy -- e.g., you can do:

    for index, item in zip(Numbers(), sequence):
        # whatever

rather than:

    for index, item in zip(range(len(sequence)), sequence):
        # whatever

and the former is a simpler form (though not as bright and
beautiful as Tim's proposed "for index indexing item in sequence"!).

The map builtin function, OTOH, does need to know the length of
each sequence in advance (and the _longest_ one controls, with
the others being 'extended' with as many 'None' as needed), so,
no such techniques (tricks?-) are available in that case.


Alex






More information about the Python-list mailing list