looping with two counter variables through a list

Alex Martelli aleaxit at yahoo.com
Wed Dec 13 03:46:07 EST 2000


"Harald Kirsch" <kirschh at lionbioscience.com> wrote in message
news:yv2zoi0ojef.fsf at lionsp093.lion-ag.de...
>
> In Tcl I can write
>
>   set mylist {0 1 2 3 4 5}
>   foreach {a b} $mylist {
>     puts $a
>   }
>
> to print the even numbers of $mylist. Obviously
>
>    mylist = [0, 1, 2, 3, 4, 5]
>    for a,b in mylist:
>      print a
>
> does not work (ValueError: unpack sequence of wrong size).

Yep: the 'for a,b in mylist' implies that mylist is a
sequence of two-item subsequences ('tuple unpacking').


> What is Python's idiom for running with more than one variable through
> a flat list?

The underlying one is looping on indices as opposed to values:

    for i in range(0, len(mylist)-1, 2):
        a = mylist[i]
        b = mylist[i+1]
        # whatever else you need


The meta-idiom one generally uses in Python for all sorts of
"impedance-matching" tasks (when the language, or a library,
offers patterns/idioms A, B, C, and you'd like to use X, Y, Z
instead in your client-code) is wrapping it up in some kind
of intermediate, auxiliary object.

Here, for example:

class LoopByN:
    def __init__(self, seq, N):
        self.seq = seq
        self.N = N
    def __getitem__(self, i):
        last = self.N * (i+1)
        if last>len(self.seq):
            raise IndexError
        return self.seq[self.N*i:last]

and then:

    for a, b in LoopByN(mylist, 2):
        # whatever

This assumes you want to 'silently slice off' the last
len(sequence) % N items of the sequence, those that do
not fit in the 'loop-by-N' idea.  If you want, e.g., to
conceptually "pad" the sequence to a multiple of N items,
or other slight semantic variation, that's pretty easy,
too (and similarly, if you want to support sequences,
that are not built-in ones, that do not support slicing
as this proposed LoopByN class is using).


Alex







More information about the Python-list mailing list