python - Accessing the index in 'for' loops?

ID : 73

viewed : 225

Tags : pythonloopslistpython

Top 5 Answer for python - Accessing the index in 'for' loops?

vote vote

92

Using an additional state variable, such as an index variable (which you would normally use in languages such as C or PHP), is considered non-pythonic.

The better option is to use the built-in function enumerate(), available in both Python 2 and 3:

for idx, val in enumerate(ints):     print(idx, val) 

Check out PEP 279 for more.

vote vote

90

Using a for loop, how do I access the loop index, from 1 to 5 in this case?

Use enumerate to get the index with the element as you iterate:

for index, item in enumerate(items):     print(index, item) 

And note that Python's indexes start at zero, so you would get 0 to 4 with the above. If you want the count, 1 to 5, do this:

count = 0 # in case items is empty and you need it after the loop for count, item in enumerate(items, start=1):     print(count, item) 

Unidiomatic control flow

What you are asking for is the Pythonic equivalent of the following, which is the algorithm most programmers of lower-level languages would use:

index = 0            # Python's indexing starts at zero for item in items:   # Python's for loops are a "for each" loop      print(index, item)     index += 1 

Or in languages that do not have a for-each loop:

index = 0 while index < len(items):     print(index, items[index])     index += 1 

or sometimes more commonly (but unidiomatically) found in Python:

for index in range(len(items)):     print(index, items[index]) 

Use the Enumerate Function

Python's enumerate function reduces the visual clutter by hiding the accounting for the indexes, and encapsulating the iterable into another iterable (an enumerate object) that yields a two-item tuple of the index and the item that the original iterable would provide. That looks like this:

for index, item in enumerate(items, start=0):   # default is zero     print(index, item) 

This code sample is fairly well the canonical example of the difference between code that is idiomatic of Python and code that is not. Idiomatic code is sophisticated (but not complicated) Python, written in the way that it was intended to be used. Idiomatic code is expected by the designers of the language, which means that usually this code is not just more readable, but also more efficient.

Getting a count

Even if you don't need indexes as you go, but you need a count of the iterations (sometimes desirable) you can start with 1 and the final number will be your count.

count = 0 # in case items is empty for count, item in enumerate(items, start=1):   # default is zero     print(item)  print('there were {0} items printed'.format(count)) 

The count seems to be more what you intend to ask for (as opposed to index) when you said you wanted from 1 to 5.


Breaking it down - a step by step explanation

To break these examples down, say we have a list of items that we want to iterate over with an index:

items = ['a', 'b', 'c', 'd', 'e'] 

Now we pass this iterable to enumerate, creating an enumerate object:

enumerate_object = enumerate(items) # the enumerate object 

We can pull the first item out of this iterable that we would get in a loop with the next function:

iteration = next(enumerate_object) # first iteration from enumerate print(iteration) 

And we see we get a tuple of 0, the first index, and 'a', the first item:

(0, 'a') 

we can use what is referred to as "sequence unpacking" to extract the elements from this two-tuple:

index, item = iteration #   0,  'a' = (0, 'a') # essentially this. 

and when we inspect index, we find it refers to the first index, 0, and item refers to the first item, 'a'.

>>> print(index) 0 >>> print(item) a 

Conclusion

  • Python indexes start at zero
  • To get these indexes from an iterable as you iterate over it, use the enumerate function
  • Using enumerate in the idiomatic way (along with tuple unpacking) creates code that is more readable and maintainable:

So do this:

for index, item in enumerate(items, start=0):   # Python indexes start at zero     print(index, item) 
vote vote

70

It's pretty simple to start it from 1 other than 0:

for index, item in enumerate(iterable, start=1):    print index, item  # Used to print in python<3.x    print(index, item) # Mirate print() after 3.x+     
vote vote

63

for i in range(len(ints)):    print(i, ints[i]) # print updated to print() in Python 3.x+  
vote vote

53

As is the norm in Python there are several ways to do this. In all examples assume: lst = [1, 2, 3, 4, 5]

1. Using enumerate (considered most idiomatic)

for index, element in enumerate(lst):     # do the things that need doing here 

This is also the safest option in my opinion because the chance of going into infinite recursion has been eliminated. Both the item and its index are held in variables and there is no need to write any further code to access the item.

2. Creating a variable to hold the index (using for)

for index in range(len(lst)):   # or xrange     # you will have to write extra code to get the element 

3. Creating a variable to hold the index (using while)

index = 0 while index < len(lst):     # you will have to write extra code to get the element     index += 1  # escape infinite recursion 

4. There is always another way

As explained before, there are other ways to do this that have not been explained here and they may even apply more in other situations. e.g using itertools.chain with for. It handles nested loops better than the other examples.

Top 3 video Explaining python - Accessing the index in 'for' loops?

Related QUESTION?