6

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?

2
  • Well, do you really need the i value, or are you just using it in order to get elements from foo? Because in Python, we iterate over containers by actually iterating over the container, not by iterating over indices. Commented Aug 25, 2011 at 2:45
  • You don't seem to understand the nature of python lists. They grow and shrink dynamically, you can always check their actual size using the len() builtin function, and iterate over every single element using the for loop... And when you need to enumerate elements, there comes enumerate() builtin function. Commented Aug 25, 2011 at 6:02

4 Answers 4

15

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.

Sign up to request clarification or add additional context in comments.

2 Comments

speaking about performance, which method will be more optimal? as @MByD and Will answered or yours?
yeah len probably would be longer but what about if just for i in list?
8

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

1 Comment

Can't do this if it's a generator or iterator, since they don't have a __len__ magic method.
4

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.

2 Comments

catch IndexError: ^ SyntaxError: invalid syntax
it's probably except instead catch
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.