indexed() generator

Michael Chermside mcherm at destiny.com
Fri Jan 25 09:29:10 EST 2002


I give it a +1 also. Here's the argument.

  * It's quite common to want to walk through the items of a list and
    ALSO have access to the current "index".

  * Two common approaches to doing this are:

     # Approach 1:
     i = 0
     for item in list:
         <code with i and item>
         i += 1

     # Approach 2:
     for i in range(len(list)):
         <code with i and list[i]>

  * The following approach is simpler and cleaner _IF_ the reader is
    familiar with the convention:

     # Approach 3:
     for i, item in indexed(list):
         <code with i and item>

  * The problems with approach 1 are that we need extra lines to
    initialize and explicitly increment i. We need to be careful to
    ensure that i is incremented properly when "break" or "continue"
    or exceptions are used, and if we intend NOT to increment i
    under one of these circumstances the reader might not notice and
    erroniously assume that i counts number of iterations.

    The problems with approach 2 are that it doesn't work with iterators,
    just sequences, that it requires the use of list[i] (which might be
    less clear than using "item"), and that the idiom "range(len(list))"
    (despite being a common Python idiom) is awkward to use.

    The problems with approach 3 are that if the reader isn't familiar
    with the indexed() function, they have to look it up.

  * So if we make indexed() a standard built-in function, then Python
    users will no longer have to look it up. The only penalty is the
    need to add yet-another-builtin. Admitedly, this is a steep price to
    pay -- but in my own code I find the need for this kind of structure
    (using both a counter AND the items in a loop) to be so common that
    for me it'd be worth it.

So... anyone else agree?

FOOTNOTE:
   My definition of indexed would be this:

     def indexed(iter):
         i = 0
         for item in iter:
             yield i, item
             i += 1

   If others wanted fancier features like "start" or "step" I wouldn't
   object, but my own inclination would be to keep it simple.

-- Michael Chermside


> FWIW, I give this idea a +1.
> Please include some form of iterindexed(seq, start=0) as a built-in in
> Python2.3.
> I've been coding something like this in many of my programs since 2.2 came
> out.
> 
> 
> Raymond
> 
>> > In article <mailman.1011750813.24541.python-list at python.org>, Delaney,
>> > Timothy wrote:
>> >
>> > >A perhaps better method would be:
>> > >
>> > >def indexed (seq, start=0)
>> > > i = start
>> > > for obj in seq:
>> > > yield i, obj
>> > > i += 1







More information about the Python-list mailing list