Reputation: 1871
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
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
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
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
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