Iterables are undoubtedly some of the most valuable objects in Python. They're incredibly versatile, helping solve a large assortment of problems. Looping through iterables is an extremely common task, but keeping track of the current element's index typically demands writing more code.
This is why the enumerate() function was built into Python all the way back in 2002!
Though it was first introduced in Python 2.3 (according to PEP 279), it remains a handy function in Python to this day.
But what exactly does the enumerate() function do? How does it work? And what can you do with it?
Let's explore the answers to these questions in detail.
What is enumerate() in Python?
Picture this:
You've coded a list in a Python program. Let's say it's a shopping list. But you need to work with each item in the list (add them, remove them, "tick" them off the list, or whatever else).
To do this, you need to know the position of every item on your list.
A Python developer unfamiliar with the enumerate() function will likely declare a counter variable for this purpose. When the loop iterates, the counter would increment.
Though this approach might work, it could throw errors. And perhaps more importantly, it's not the most "Pythonic" solution to the problem.
The enumerate() function retrieves the index value of each element besides the element itself. In other words, it allows you to loop over iterables while simultaneously tracking the index value of each item.
Using enumerate() rather than writing a counter variable that iterates is the more Pythonic solution. It's simple, short, readable, and beautiful – exactly how this programming language's philosophy explains it should be written.
So far, you've understood what the enumerate() function does. Now, let's take a look at how to write it so it's syntactically sound.
The Syntax of the enumerate() Function
Understanding the enumerate() function's syntax is essential as you need to know what arguments it accepts and what exactly it returns.
The syntax of this function is:
enumerate(<iterable>, startValue=0) |
The first parameter, <iterable>, is where you must mention a Python iterable. Bear in mind that this function does not work if an iterable isn't mentioned as a parameter.
The startValue parameter, on the other hand, need not be mentioned. But if you mention it, you must set it to the number you want the starting index value of the list to be.
It is set to zero by default, so the index value of the first item in an iterable will be zero when the parameter is not explicitly mentioned.
Interestingly, the function itself returns an iterator. The enumerate object it returns has pairs of (index, element) values for every item in the iterable it was supplied.
You can use the iterator that enumerate() returns in a for loop. This way, you can access both the item and its index value in one go.
To see it in action, you'll need to put together a list:
pets = ('Dogs', 'Cats', 'Turtles', 'Rabbits')
Then you'll need this line of code:
for i, pet in enumerate(pets): print i, pet
Your output should be as follows:
0 Dogs 1 Cats 2 Turtles 3 Rabbits
As you can see, these results not only print out the contents of the list, but also print them out with their corresponding index orders.
As expected, the index value of the first item on the list is zero. The for loop unpacks the returned enumerate object and retrieves the index values and corresponding items.
You can also use the enumerate() function to create an output of the list indices/values with the indices changed according to your code.
for i, pet in enumerate(pets, 7):
print i, pet
This code changes the function so that the first value in the list is assigned the index number 7 for the purposes of your enumeration. In this case, your results would be as follows:
7 Dogs
8 Cats
9 Turtles
10 Rabbits
With this, you've gotten a handle on the basic workings of the enumerate() function.
But if you want to use it effectively, you must first learn how to use the function for easy problem-solving. Let's look at some essential use cases of the enumerate() function.
Most Helpful Uses of the enumerate() Function
When a developer works with an iterable, the index value and the items themselves are of equal importance (in most cases). Some of the more common uses cases for the enumerate() include:
#1 enumerate() in Python Lists
Lists are data structures built into Python that enable you to store several elements in one variable.
You can think of a list as a basket that you can throw different things into, and just like a list, the basket holds your items in the same order you put them in.
There's a lot of different ways you can use the enumerate() function with lists in Python:
Using enumerate() to Access Items and Their Corresponding Indices
The enumerate() function is an excellent way to access a list's items and the indices in an efficient and clean way. Let's see it in action:
colors = ['red', 'green', 'blue', 'yellow', 'purple'] for idx, color in enumerate(colors): print(f"At position {idx}, the color is {color}.") |
In this example, we have a list of colors, and we use enumerate() to iterate through the list.
Inside the for loop, idx represents the index of the current color, and color represents the value of the color at that index. The print() statement then displays the index and the color.
The output of the code is:
At position 0, the color is red. At position 1, the color is green. At position 2, the color is blue. At position 3, the color is yellow. At position 4, the color is purple. |
Using enumerate() to Modify Items in a List
One of the most useful capabilities of the enumerate() function is the ability to modify items in a list. You can do this by using the item's corresponding index before modifying the item.
Take this list, for instance:
values = [10, 20, 30, 40, 50] |
Let's say you want to modify all the items in the list. Specifically, you want to multiply each value by 3. You can do this by writing a simple for loop, like so:
for index, value in enumerate(values): values[index] = value * 3 print(f"At index {index}, the new value is {values[index]}.") |
In this example, we have a list called values, and we use enumerate() to iterate through it. Inside the for loop, 'index' represents the current element's index, and 'value' represents the value at that index.
We then multiply each element by 3 and assign the result to the same index, effectively modifying the list's elements in place.
As you'd expect, the output of the code is:
At index 0, the new value is 30. At index 1, the new value is 60. At index 2, the new value is 90. At index 3, the new value is 120. At index 4, the new value is 150. |
Comparing the Items in Two Lists with enumerate()
The enumerate() function makes it easy for you to access index values, which are essential if you want to access and compare the elements in two lists.
Here's how you can write a program to point out the differences in the values of two lists:
first_list = [10, 20, 30, 40, 50] second_list = [10, 20, 35, 0, 55] for index, item1 in enumerate(first_list): item2 = second_list[index] if item1 != item2: print(f"Difference at index {index}: {item1} (first_list) vs {item2} (second_list)") |
In this example, we have two lists, first_list and second_list. We use enumerate() to iterate through first_list, and at each index, we compare the corresponding elements in both lists.
If there's a difference, it prints a message indicating the index, the value in first_list, and the value in second_list at that index. Here's the output of the code:
Difference at index 2: 30 (first_list) vs 35 (second_list) Difference at index 3: 40 (first_list) vs 0 (second_list) Difference at index 4: 50 (first_list) vs 55 (second_list) |
#2 enumerate() in Python Tuples
Tuples are collections of items, just like lists, except that once you create a tuple, you cannot modify it. This is why tuples are called immutable data structures.
There are two interesting ways to use the enumerate() function with tuples in Python:
Finding a Specific Element in a Tuple with enumerate()
Developers are often in situations where they need to determine whether an item is present in a tuple or not.
Let's see how you can do this with an example:
foods = ('pizza', 'burger', 'sushi', 'pasta', 'taco') search_item = 'sushi' for index, food in enumerate(foods): if food == search_item: print(f"'{search_item}' found at position {index}") |
In this example, we have a tuple named foods, and we're searching for the item 'sushi.'
The enumerate() function is used to loop through the tuple, and inside the loop, we check if the current food matches the search_item. If a match is found, it prints the item and its position in the tuple.
Here's the output of the program:
'sushi' found at position 2 |
Creating a dictionary with a Tuple Using enumerate()
It's not uncommon for developers to need to transform one data structure into another. Interestingly, the enumerate() function allows you to create a dictionary with a tuple.
Here's some code to illustrate how you can do this:
animals = ('cat', 'dog', 'elephant', 'giraffe', 'kangaroo') animal_dict = {idx: animal for idx, animal in enumerate(animals)} print(animal_dict) |
Here, we have a tuple named animals and use enumerate() to create a dictionary named animal_dict.
Each key in the dictionary represents the index of the corresponding animal in the tuple, and the values are the animal names. The print statement displays the resulting dictionary. As you might have guessed, the output of the program is:
{0: 'cat', 1: 'dog', 2: 'elephant', 3: 'giraffe', 4: 'kangaroo'} |
#3 enumerate() in Python Dictionaries
Dictionaries are unordered collections of data in key-value pairs. You can modify a dictionary after its creation, but each item in a dictionary must have a unique key.
Here are two common use cases of the enumerate() function with dictionaries:
Traversing Through the Keys and Values of a Dictionary
When you use enumerate(), it adds a counter to an iterable, giving you access to the index value of the current item. So, you can use the function to traverse a dictionary and find the keys and values associated with every item.
Let's look at an example to see how this works:
sample_dict = {10: 'apple', 20: 'banana', 30: 'cherry', 40: 'date'} for i, key in enumerate(sample_dict): value = sample_dict[key] print("Key:", key, "Value:", value) |
In this code, we use enumerate() to iterate over the keys of the dictionary. Then, the loop count held by "i" is printed for each iteration before retrieving the corresponding value from the dictionary and print both the key and the value.
The output of the script is:
Key: 10 Value: apple Key: 20 Value: banana Key: 30 Value: cherry Key: 40 Value: date |
It's interesting to note that you can accomplish the same result using the items() method, and this would be the more Pythonic approach to achieving this task.
The items() method returns a collection of key-value pairs you can iterate. Let's see how you can apply the items() method:
sample_dict = {10: 'apple', 20: 'banana', 30: 'cherry', 40: 'date'} for key, value in sample_dict.items(): print("Key:", key, "Value:", value) |
In this example, we directly iterate over the dictionary sample_dict.
The code prints both the key and the value for each item in the dictionary. Using enumerate() is not necessary when iterating over dictionaries because you can directly access the key-value pairs with .items().
The output of the code is:
Key: 10 Value: apple Key: 20 Value: banana Key: 30 Value: cherry Key: 40 Value: date |
So far, you've familiarized yourself with most of what you can accomplish with Python's enumerate() function.
However, this is not the end. There's a lot more you can do with enumerate(). Let's explore some of its advanced capabilities.
Python enumerate(): Advanced Use Cases
Though the enumerate() function seems simple to use, it offers some powerful capabilities that come in handy in many circumstances. Here's a look at three advanced uses of enumerate().
In this section, we will go beyond the basics and explore some of the advanced use cases of the enumerate function in Python.
#1 enumerate() in Classes
If you've been honing your Python skills for a while, you may encounter a situation where you'd need to use the enumerate() function with custom classes.
To pull this off, you will need to implement the iter() method in the class. The method makes the class iterable.
Let's assume you have a custom class called "Color," and you want to work with a dictionary inside this class having some colors and their hex values:
class Color: def __init__(self, colors: dict): self.colors = colors def __iter__(self): return iter(self.colors.items()) custom_colors = Color({"yellow": "#FFFF00", "purple": "#800080", "pink": "#FFC0CB"}) for index, (name, hex_value) in enumerate(custom_colors): print(f"{index}: {name} => {hex_value}") |
In this example, the Color class has an __iter__ method that allows it to be iterable.
The enumerate() function then works with instances of this class, and you can iterate through the key-value pairs in the dictionary stored in the class to print the index, color name, and hex value.
As you expect, the output of the code is:
0: yellow => #FFFF00 1: purple => #800080 2: pink => #FFC0CB |
#2 enumerate() in Enum Classes
Python's built-in Enum class helps developers create enumeration types, which have integer values auto-assigned to them.
But here's what's great:
You can use the enumerate() function with an Enum class just like any other iterable. Let's see an example:
from enum import Enum, auto class Planet(Enum): MERCURY = auto() VENUS = auto() EARTH = auto() MARS = auto() JUPITER = auto() SATURN = auto() URANUS = auto() NEPTUNE = auto() for index, planet in enumerate(Planet): print(f"{index}: {planet.name} => {planet.value}") |
In this example, the Planet class is defined as an Enum with various planet names and associated values. The enumerate() function is used to iterate over these planets, and for each planet, it prints the index, planet name, and its associated value.
Here's the output of the script:
0: MERCURY => 1 1: VENUS => 2 2: EARTH => 3 3: MARS => 4 4: JUPITER => 5 5: SATURN => 6 6: URANUS => 7 7: NEPTUNE => 8 |
#3 enumerate() for Reversing the Order of Items
Interestingly, you can use the built-in reversed() function with enumerate() to reverse the order of items in a mutable iterable.
It's pretty straightforward. Here's an example:
original_list = ["grape", "pear", "orange"] for index, item in enumerate(reversed(original_list)): print(f"{index}: {item}") |
As you can see, we have a list called original_list, and we use reversed() to reverse the order of its items.
Then, we use enumerate() to iterate over the reversed list and print the index and each item. This way, you can process the items in the reversed order.
Bear in mind that the reversed() function doesn't alter the original iterable. Instead, it creates a new iterator and shows the items in reverse order.
Here's the code's output:
0: orange 1: pear 2: grape |
Conclusion
As you sharpen your Python skills and scale higher peaks of mastery, learning to use the enumerate() function inside and out makes your code as efficient and readable as it gets.
This handy function gives you easy access to the items and their index values, eliminating the need for the traditional counter variable.
Remember to try your hand at writing a few scripts with this function to get a feel for it.