Templar
Templar

Reputation: 1871

Doing loop while list has indexes in python

Let's say we have list with unknown number of indexes, is it possible to do something like

i=0
while foo[i]:
    ...
    i+=1

In my example I get error because index will be out of range, but I think you got what I want?

Upvotes: 6

Views: 75514

Answers (4)

Rahul
Rahul

Reputation: 240

You can either use a for loop or while loop.
Python gives various ways to iterate a list without knowing its index.

For loop:

for i in li:

or you can use

for i in range(len(li))

In this case the iterator will be an Integer, It comes in handy in various situations.

While loop:

while i<len(li):
   ----
   i = i+1

I prefer using for loop when it comes to iterating list in python

Upvotes: 0

Nate
Nate

Reputation: 12849

what you are looking for is:

for i, elem in enumerate(foo):
    #i will equal the index
    #elem will be the element in foo at that index
    #etc...

the enumerate built-in takes some sequence (like a list, or a generator), and yields a tuple, the first element of which contains the iteration number, and the second element of which contains the value of the sequence for that iteration.

Since you specifically ask about an "unknown number of indexes", I also want to clarify by adding that enumerate works lazily. Unlike len, which needs to calculate/evaluate an entire sequence in advance (assuming that you are working with something more complicated than a simple list), and would thus fail for an infinite list, and take an indeterminate amount of time for some arbitrary generator function (which would then need to be run again, possibly leading to side effects), enumerate only evaluates the next sequence in the list. This can be shown using the fact that it will perform as expected on the easiest to make example of a sequence with an unknown number of entries: an infinite list:

import itertools
for i, elem in enumerate(itertools.cycle('abc')):
    #This will generate -
    # i = 0, elem = 'a'
    # i = 1, elem = 'b'
    # i = 2, elem = 'c'
    # i = 3, elem = 'a'
    # and so on, without causing any problems.

EDIT - in response to your comments:

Using for ... enumerate ... is inherently more expensive than just using for (given that you have the overhead of doing an additional enumerate). However, I would argue that if you are tracking the indexes of your sequence elements, that this tiny bit of overhead would be a small price to pay for the very pythonic presentation it affords (that is to say, i=0; i += 1 is a very C-style idiom).

After doing a little bit of searching, I dug up (and then agf corrected the url for) the source code for the enumerate function (and additionally, the reversed function). It's pretty simple to follow, and it doesn't look very expensive at all.

Upvotes: 14

morningstar
morningstar

Reputation: 9162

Not the smoothest way, but you can do exactly what you did, but catch the exception.

i = 0
try:
    while foo[i]:
        ...
        i += 1
except IndexError:
    pass

That would end at any point in the list where the element has a value that tests as false, or would process the whole list if there is no false value. If what you want is to always process the whole list even if it contains false values, change while foo[i] to while 1. You would have to access foo[i] in the body of the loop (I assume you want to anyway) to trip the exception and avoid an infinite loop.

Upvotes: 4

Will
Will

Reputation: 871

if you have a python list, you can iterate through the list with a for loop:

for i in list

if you have to use the while loop, you can try

i=0
while i<len(foo):
  ...
  i+=1

Upvotes: 8

Related Questions