Skip to main content

Python Enumerate Tutorial

Elena Kosourova ,
May 20, 2022 9 min read
LinkedInFacebookTwitterCopy
Discover what the Python enumerate function is and how you can use it in your day-to-day data science tasks.

Python Enumerate Tutorial Image

In this tutorial, we'll discuss what the enumerate() function in Python is, when it's used, what kind of objects it creates, what syntax it has, and how it works. Then, we'll see some examples of enumerating different types of objects in Python, the alternatives of the enumerate() function, and why they are less suitable for the same task.

What is Enumerate in Python and When is It Used?

The enumerate() function is a Python built-in function that takes an iterable (a collection of items or any other Python object that supports iteration, such as tuples, lists, sets, or strings), iterates through its items under the hood, and returns an enumerate object. In other words, this function assigns a count incrementing by 1 to each item of an iterable and helps us track iterations while looping through that object. After creating an enumerate object, we can then convert it into a list, a tuple, or a dictionary (using the list(), tuple(), or dict() functions respectively), or to loop directly through this object to access both the items and their corresponding indices.

Using the enumerate() function is useful from the standpoint of its memory and computing efficiency compared to using for-loops since it returns the index and the corresponding item at one go.

Syntax

The syntax of the enumerate() function is very simple:

enumerate(iterable, start=0)

Here, iterable is an iterable object that we want to enumerate, and start is an optional parameter defining the starting index of the counter (by default, it will be a typical Python 0-based index).

Note that applying the enumerate() function on an iterable doesn't change the initial object itself. Instead, the resulting enumerate object should be assigned to a variable if we want to be able to use it further.

Now, let's see how this function works on different types of Python iterables.

Enumerating a List

First, we'll apply the enumerate() function on a Python list:

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
print(type(enumerated_drinks))
print(enumerated_drinks)

 Output:

<class 'enumerate'>
<enumerate object at 0x000002DC3A1145C0>

The type of the resulting object is enumerate, and when we tried to print it out, we just confirmed once again the object type and where it's stored in the computer memory. Let's try to access the first element of this object in the same way as we would do with a Python list or a tuple:

print(enumerated_drinks[0])

 Output:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/1233607596.py in <module>
----> 1 print(enumerated_drinks[0])

TypeError: 'enumerate' object is not subscriptable

We got an error that indicates that the components of an enumerate object aren't accessible in this way. Instead, for this purpose, we need to convert it into a list, a tuple, or a dictionary, or loop directly through the enumerate object. Let's convert our enumerate object into a list:

list_enumerated_drinks = list(enumerated_drinks)
print(list_enumerated_drinks)

 Output:

[(0, 'tea'), (1, 'coffee'), (2, 'cappuccino'), (3, 'lemonade')]

Now, we perfectly see the inner structure of the resulting list: each item represents a 2-element tuple where the first element is the index of the corresponding item in the original list and the second is the item itself. We can use a common indexing approach to access the elements of this list:

print(list_enumerated_drinks[0])
print(list_enumerated_drinks[0][1])

 Output:

(0, 'tea')
tea

Let's try now to convert an enumerate object created from the original list into a tuple. In addition, this time, we'll set the start optional parameter to 1:

tuple_enumerated_drinks = tuple(enumerate(drinks, start=1))
print(tuple_enumerated_drinks)

 Output:

((1, 'tea'), (2, 'coffee'), (3, 'cappuccino'), (4, 'lemonade'))

The inner structure of the above tuple is identical to the one of the list created earlier. However, this time, we also changed the count making it more "human-style" rather than Python 0-based indexing.

There is one interesting method of an enumerate object that is worth mentioning here: the next() method. Let's re-create the enumerated_drinks object and try this method in action:

enumerated_drinks = enumerate(drinks)
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))

 Output:

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/330134057.py in <module>
      4 print(next(enumerated_drinks))
      5 print(next(enumerated_drinks))
----> 6 print(next(enumerated_drinks))

StopIteration: 

As we see, every time we call this method on an enumerate object, it returns the next item from it (and we can confirm once again that each item is a 2-element tuple containing the corresponding count-item pair). When all the items are finished, the enumerate object becomes exhausted, and the attempt to call the next() method on it results in throwing a StopIteration error. Indeed, if we try now to convert this enumerate object into a list, we'll see that it's empty

print(list(enumerated_drinks))

 Output:

[]

This means that at each application of the next() method on an enumerate object, an item is taken from the object, so each time it becomes smaller, up to total exhaustion. We'll see this property of enumerate objects also later when we discuss applying for-loops on them.

If you want to learn more about Python lists and other basic concepts of Python, you can take the Introduction to Python course of DataCamp.

Enumerating a Tuple

The application of the enumerate() function on a tuple is identical to the same on a list:

drinks = ('tea', 'coffee', 'cappuccino', 'lemonade')
enumerated_drinks = enumerate(drinks)
print(enumerated_drinks)

 Output:

<enumerate object at 0x000002DC3A098D40>

Again, we obtained an enumerate object whose items are inaccessible with common Python indexing. Let's transform this object into another one, this time in a dictionary:

dict_enumerated_drinks = dict(enumerated_drinks)
print(dict_enumerated_drinks)

 Output:

{0: 'tea', 1: 'coffee', 2: 'cappuccino', 3: 'lemonade'}

Each key:value pair of the resulting dictionary represents the corresponding count-item pair. We can access the values of the dictionary in a common Pythonic way:

print(dict_enumerated_drinks[0])
print(dict_enumerated_drinks[3])

 Output:

tea
lemonade

If you want to dive deeper into Python dictionaries and pandas explore the Intermediate Python course. 

Enumerating a String

Since Python strings are the sequences of characters and hence also iterable objects, we can also create an enumerate object for a string:

enumerated_hello_world = enumerate('Hello, World!', start=10)
print(enumerated_hello_world)

 Output:

<enumerate object at 0x000002DC3A145C40>

As we did earlier, let's convert this object into a list:

list_enumerated_hello_world = list(enumerated_hello_world)
print(list_enumerated_hello_world)

 Output:

[(10, 'H'), (11, 'e'), (12, 'l'), (13, 'l'), (14, 'o'), (15, ','), (16, ' '), (17, 'W'), (18, 'o'), (19, 'r'), (20, 'l'), (21, 'd'), (22, '!')]

We see the already-familiar 2-element tuples, where the first element is the count of the corresponding character of the string (in this case – starting from 10), and the second – the character itself. The white space and punctuation marks are also counted.

Let's re-create the enumerated_hello_world object, this time without start=10, and apply the next method on it:

enumerated_hello_world = enumerate('Hello, World!')
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
​
# Creating a list from the remaining enumerate object
print(list(enumerated_hello_world))

 Output:

(0, 'H')
(1, 'e')
(2, 'l')
(3, 'l')
(4, 'o')
(5, ',')
[(6, ' '), (7, 'W'), (8, 'o'), (9, 'r'), (10, 'l'), (11, 'd'), (12, '!')]

In the last line of the above piece of code, we stopped applying the next() method and converted the enumerated_hello_world object into a list. The resulting list contains the remaining characters of the initial enumerate object after multiple applications of the next() method on it.

Enumerating through a For-Loop

Finally, let's see how the enumerate() function works in combination with a for-loop:

for item in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
  print(item)

 Output:

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')

At each iteration, the corresponding count-item tuple is returned, just like it happens when we use the next() method. Even if it's not obvious from the above piece of code, the enumerate object also loses its items (i.e., the 2-element tuples) one by one at each iteration. To demonstrate it, let's rewrite the above piece of code in a different form and check the length of the resulting list after finishing all the iterations:

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
​
for item in enumerated_drinks:
  print(item)
 
print(list(enumerated_drinks))

 Output: 

(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')
[]

As it was with the application of the next() method, iterating through an enumerate object gradually exhausts it.

Let's, however, return to the previous piece of code. How can we access each element separately from each 2-element tuple? For this purpose, we'll add one more iteration variable and unpack the tuples:

for count, drink in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
  print(count, drink)

 Output:

0 tea
1 coffee
2 cappuccino
3 lemonade

Above, we returned two variables for each tuple: one for the count of the item and one for the item itself.

Note that we can also implement the same operation as above without using the enumerate() function. For example, we can introduce a counter variable outside the loop and increment it by 1 at each iteration of the loop:

count = 0
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
  print(count, drink)
  count += 1

 Output:

0 tea
1 coffee
2 cappuccino
3 lemonade

Alternatively, we can use a combination of the range() and len() functions on a predefined list (or a tuple, a string, etc.):

drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
  print(count, drinks[count])

 Output:

0 tea
1 coffee
2 cappuccino
3 lemonade

Moreover, in both of these alternatives of the enumerate() function, we still can adjust the count variable to start not from zero:

count = 1
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
  print(count, drink)
  count += 1
​
print('\n')
 
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
  print(count + 1, drinks[count])

 Output:

1 tea
2 coffee
3 cappuccino
4 lemonade


1 tea
2 coffee
3 cappuccino
4 lemonade

However, in comparison to the application of the enumerate() function, both approaches above are more clumsy, bug-prone (e.g., we can forget to update the counter manually at each iteration), and require more code. Hence, using the enumerate() function is the most Pythonic approach anytime we need to access both the count and the item of an iterable at each iteration.

Conclusion

In this tutorial, we learned many things about the enumerate() function in Python, including its many uses, potential alternatives, and why it is ultimately more effective than its alternatives.  The enumerate() function won’t be familiar to most beginning Python users, and even advanced programmers may not be aware of this incredibly useful function. 

If you would like to learn more about enumerate(), consider the Python Data Science Toolbox (Part 2) course that explores iterators and iterables in detail and offers interactive exercises to practice new skills. In addition, if you want to master other Python concepts, you may be interested in Learn Python with DataCamp which provides various skill and career tracks, cheat sheets, tutorials, Python certifications, and assessment tests. 


Posted in:
Data Science
Share on:LinkedInLinkedInFacebookFacebookTwitterTwitterCopyCopy link

← Back to tutorial