Home Accessing the index in Python 'for' loops

# Accessing the index in Python 'for' loops

Joan Venge
1#
Joan Venge Published in 2009-02-06 22:47:54Z
 How do I access the index itself for a list like the following? ints = [8, 23, 45, 12, 78]  When I loop through it using a for loop, how do I access the loop index, from 1 to 5 in this case?
Peter Mortensen
2#
Peter Mortensen Reply to 2016-09-17 10:13:51Z
 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.
David Hanak
3#
David Hanak Reply to 2009-02-06 22:49:23Z
 for i in range(len(ints)): print i, ints[i] 
Charlie Martin
4#
Charlie Martin Reply to 2009-02-06 22:57:26Z
 Old fashioned way: for ix in range(len(ints)): print ints[ix]  List comprehension: [ (ix, ints[ix]) for ix in range(len(ints))] >>> ints [1, 2, 3, 4, 5] >>> for ix in range(len(ints)): print ints[ix] ... 1 2 3 4 5 >>> [ (ix, ints[ix]) for ix in range(len(ints))] [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)] >>> lc = [ (ix, ints[ix]) for ix in range(len(ints))] >>> for tup in lc: ... print tup ... (0, 1) (1, 2) (2, 3) (3, 4) (4, 5) >>> 
Martijn Pieters
5#
Martijn Pieters Reply to 2012-05-24 20:03:12Z
 According to this discussion: http://bytes.com/topic/python/answers/464012-objects-list-index Loop counter iteration The current idiom for looping over the indices makes use of the built-in 'range' function: for i in range(len(sequence)): # work with index i  Looping over both elements and indices can be achieved either by the old idiom or by using the new 'zip' built-in function[2]: for i in range(len(sequence)): e = sequence[i] # work with index i and element e  or for i, e in zip(range(len(sequence)), sequence): # work with index i and element e  via http://www.python.org/dev/peps/pep-0212/
Matheus Araujo
6#
Matheus Araujo Reply to 2018-02-14 04:41:06Z
 I don't know if the following is pythonic or not, but it uses the Python function enumerate and prints the index and the value. int_list = [8, 23, 45, 12, 78] for index, value in enumerate(int_list): print(index, value)  Output: 0 8 1 23 2 45 3 12 4 78 
Peter Mortensen
7#
Peter Mortensen Reply to 2016-09-17 10:15:03Z

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

for index in enumerate(iterable, start=1):
print index


## Note

Important hint, though a little misleading, since index will be a tuple (idx, item) here. Good to go.

Aaron Hall
8#
Aaron Hall Reply to 2016-09-17 10:45:55Z

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

Use enumerate:

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


And note that indexes start at zero, so you would get 0 to 4 with this. If you want the count, I explain that below.

# 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.

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)

x0x
9#
 ints = [9, 23, 45, 12, 78] ints.extend([1,2,3,4,5,6,7,8]) for idx, val in enumerate(ints): print(idx,val)  This way you can extend a list. Extend means you can add multiple values at a time. To append this list you have to write the code given below: ints = [9, 23, 45, 12, 78] ints.append([1]) for idx, val in enumerate(ints): print(idx,val)  This way you can add a single value at a time. If you write ints.append([1]) so this will create a sub list for this element.
Thorsten S.
10#
Thorsten S. Reply to 2015-05-25 23:05:19Z
 First of all, the indexes will be from 0 to 4. Programming languages start counting from 0; don't forget that or you will come across an index out of bounds exception. All you need in the for loop is a variable counting from 0 to 4 like so: for x in range(0, 5):  Keep in mind that I wrote 0 to 5 because the loop stops one number before the max. :) To get the value of an index use list[index] 
Veltro
11#
 You can do it with this code: ints = [8, 23, 45, 12, 78] index = 0 for value in (ints): index +=1 print index, value  Use this code if you need to reset the index value at the end of the loop: ints = [8, 23, 45, 12, 78] index = 0 for value in (ints): index +=1 print index, value if index >= len(ints)-1: index = 0 
Community
12#
 The fastest way to access indexes of list within loop in Python 2.7 is to use the range method for small lists and enumerate method for medium and huge size lists. Please see different approaches which can be used to iterate over list and access index value and their performance metrics (which I suppose would be useful for you) in code samples below: from timeit import timeit # Using range def range_loop(iterable): for i in range(len(iterable)): 1 + iterable[i] # Using xrange def xrange_loop(iterable): for i in xrange(len(iterable)): 1 + iterable[i] # Using enumerate def enumerate_loop(iterable): for i, val in enumerate(iterable): 1 + val # Manual indexing def manual_indexing_loop(iterable): index = 0 for item in iterable: 1 + item index += 1  See performance metrics for each method below: from timeit import timeit def measure(l, number=10000): print "Measure speed for list with %d items" % len(l) print "xrange: ", timeit(lambda :xrange_loop(l), number=number) print "range: ", timeit(lambda :range_loop(l), number=number) print "enumerate: ", timeit(lambda :enumerate_loop(l), number=number) print "manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number) measure(range(1000)) # Measure speed for list with 1000 items # xrange: 0.758321046829 # range: 0.701184988022 # enumerate: 0.724966049194 # manual_indexing: 0.894635915756 measure(range(10000)) # Measure speed for list with 100000 items # xrange: 81.4756360054 # range: 75.0172479153 # enumerate: 74.687623024 # manual_indexing: 91.6308541298 measure(range(10000000), number=100) # Measure speed for list with 10000000 items # xrange: 82.267786026 # range: 84.0493988991 # enumerate: 78.0344707966 # manual_indexing: 95.0491430759  As the result, using range method is the fastest one up to list with 1000 items. For list with size > 10 000 items enumerate is the winner. Adding some useful links below: What is the difference between range and xrange functions in Python 2.X? What is faster for loop using enumerate or for loop using xrange in Python? range(len(list)) or enumerate(list)?
jamylak
13#

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.

Anurag Misra
14#
Anurag Misra Reply to 2017-08-24 06:15:31Z
 Best solution for this problem is use enumerate in-build python function. enumerate return tuple first value is index second value is element of array at that index In [1]: ints = [8, 23, 45, 12, 78] In [2]: for idx, val in enumerate(ints): ...: print(idx, val) ...: (0, 8) (1, 23) (2, 45) (3, 12) (4, 78) 
Ashok Kumar Jayaraman
15#
Ashok Kumar Jayaraman Reply to 2018-02-07 14:04:10Z
 You can also try this: data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok'] x = [] for (i, item) in enumerate(data): a = (i, str(item).split('.')) x.append(a) for index, value in x: print(index, value)  The output is 0 ['itemA', 'ABC'] 1 ['itemB', 'defg'] 2 ['itemC', 'drug'] 3 ['itemD', 'ashok'] 
Gary R.
16#
Gary R. Reply to 2018-02-14 19:20:43Z
 You've received a number of answers explaining enumerate, but if you only need the index for accessing matching entries in two lists, there's another way that's cleaner and simpler in Python 3: zip. For example, if you're using the index to pull out corresponding names for the numbers in your list, you could do it like this: ints = [8, 23, 45, 12, 78] names = ["John", "Sue", "Johannes", "Patel", "Ian"] for int, name = zip(ints, names): print("{} - {}".format(name, int)  That would produce 8 - John 23 - Sue 45 - Johannes 12 - Patel 78 - Ian 
 You need to login account before you can post.
Processed in 0.308416 second(s) , Gzip On .