Enumerate
enumerate()
We’ve seen how to iterate over the elements of an iterable in a for
loop.
for e in lst:
print(e)
Sometimes, however, it’s helpful to have both the element and the index of the element at each iteration. One common application requiring an element and the index of the element is in calculating an alternating sum. Alternating sums appear in analysis, number theory, combinatorics, many with real-world applications.
An alternating sum is simply a summation where the signs of terms alternate. Rather than
x_0 + x_1 + x_2 + x_3 + x_4 + x_5 + \ldots
where the signs are all positive, an alternating sum would look like this:
x_0 - x_1 + x_2 - x_3 + x_4 - x_5 + \ldots
Notice that we alternate addition and subtraction.
There are many ways we could implement this. Here’s one rather clunky example (which assumes we have a list of numerics named lst
):
= 0
alternating_sum
for i in range(len(lst)):
if i % 2: # i is odd, then we subtract
-= lst[i]
alternating_sum else:
+= lst[i] alternating_sum
This works. Strictly speaking from a mathematical standpoint it is correct, but for i in range(len(lst))
and then using i
as an index into lst
is considered an “anti-pattern” in Python. (Anti-patterns are patterns that we should avoid.)
So what’s a programmer to do?
enumerate()
to the rescue! Python provides us with a handy built-in function called enumerate()
. This iterates over all elements in some sequence and yields a tuple of the index and the element at each iteration.
Here’s the same loop implemented using enumerate()
:
= 0
alternating_sum
for i, e in enumerate(lst):
if i % 2:
-= e
alternating_sum else:
+= e alternating_sum
We do away with having to call len(list)
and we do away with indexed reads from lst
.
Here’s another example, where we wish to perform indexed writes into a list in a loop. Say we wanted to increment every element in a list of numeric values by a constant. Here’s how we can do this with enumerate()
.
= 5
incr = [1, 2, 3, 4]
lst
for i, e in enumerate(lst):
= e + incr lst[i]
That’s it! After this code has run, lst
has the value [6, 7, 8, 9]
.
In many cases, use of enumerate()
leads to cleaner and more readable code. But how does it work? What, exactly, does enumerate()
do?
If we pass some iterable—say a list, tuple, or string—as an argument to enumerate()
we get a new iterable object back, one of type enumerate
(this is a new type we haven’t seen before). When we iterate over an enumerate object, it yields tuples. The first element of the tuple is the index of the element in the original iterable. The second element of the tuple is the element itself.
That’s a lot to digest at first, so here’s an example:
= ['a', 'b', 'c', 'd']
lst for i, element in enumerate(lst):
print(f"The element at index {i} is '{element}'.")
This prints:
The element at index 0 is 'a'.
The element at index 1 is 'b'.
The element at index 2 is 'c'.
The element at index 3 is 'd'.
The syntax that we use above is tuple unpacking (which we saw in an earlier chapter). When using enumerate()
this comes in really handy. We use one variable to hold the index and one to hold the element. enumerate()
yields a tuple, and we unpack it on the fly to these two variables.
Let’s dig a little deeper using the Python shell.
>>> lst = ['a', 'b', 'c']
>>> en = enumerate(lst)
>>> type(en) # verify type is `enumerate`
<class 'enumerate'>
>>> for t in en: # iterate `en` without tuple unpacking
... print(t)
...
(0, 'a')
(1, 'b')
(2, 'c')
So you see, what’s yielded at each iteration is a tuple of index and element. Pretty cool, huh?
Now that we’ve learned a little about enumerate()
let’s revisit the alternating sum example:
= 0
alternating_sum
for i, e in enumerate(lst):
if i % 2:
-= e
alternating_sum else:
+= e alternating_sum
Recall that we’d assumed lst
is a previously defined list of numeric elements. When we pass lst
as an argument to enumerate()
we get an enumerate
object. When we iterate over this object, we get tuples at each iteration. Here we unpack them to variables i
and e
. i
is assigned the index, and e
is assigned the element.
If you need both the element and its index, use enumerate()
.
Copyright © 2023–2025 Clayton Cafiero
No generative AI was used in producing this material. This was written the old-fashioned way.