In Post #34, we learned that the for
loop is the best way to iterate over the items in a list. The simple for fruit in fruits:
syntax is clean and effective for when you only care about the items themselves. But what happens when you need to know the position of an item as you’re looping? What if you need both the item and its index?
In this post, we’ll learn the “Pythonic” way to solve this common problem using the built-in enumerate()
function.
The Problem: Tracking the Index Manually
Let’s say we want to print each item from a list along with its index number, like “Item #0 is apple”, “Item #1 is banana”, and so on. Without a special tool, our first instinct might be to create a manual counter variable that we increment on each pass of the loop.
fruits = ["apple", "banana", "cherry"]
index = 0
print("Looping with a manual counter:")
for fruit in fruits:
print(f"Item at index {index} is {fruit}")
index += 1
This code works, but it’s not ideal. It adds extra lines of code (initializing and incrementing index
) and introduces a new variable that we have to manage ourselves. It’s easy to forget the index += 1
line, which would be a bug. Python provides a much better way.
The Solution: The enumerate()
Function
The enumerate()
function is a Pythonic best-practice that elegantly solves this problem. It takes a list (or any iterable) and, on each iteration, gives you back a pair of values: the index and the item at that index.
The syntax looks like this:
for index, item in enumerate(my_list):
On each pass of the loop, enumerate
provides the index and item, and the for
loop automatically “unpacks” them into our two temporary variables, index
and item
.
Let’s rewrite our previous example using this superior method.
fruits = ["apple", "banana", "cherry"]
print("\nLooping with enumerate():")
for index, fruit in enumerate(fruits):
print(f"Item at index {index} is {fruit}")
The output is the same, but the code is cleaner, more concise, and less prone to errors. The enumerate()
function handles all the index-tracking for us behind the scenes. This is the preferred way to write this kind of loop in Python.
Changing the Starting Number
By default, enumerate()
starts counting from 0
, which is perfect for programming logic that uses zero-based indexing. But sometimes, you might want to create a numbered list for a human reader that starts at 1
. The enumerate()
function has an optional start
argument for exactly this purpose.
Let’s create a nicely formatted shopping list for a user.
shopping_list = ["milk", "eggs", "bread"]
print("\nYour shopping list:")
for item_number, item in enumerate(shopping_list, start=1):
print(f"{item_number}. {item}")
By adding start=1
, the count will begin at 1 instead of 0. The output is much more user-friendly:
Your shopping list:
1. milk
2. eggs
3. bread
What’s Next?
The enumerate()
function is a core part of writing clean, professional Python code. Whenever you find yourself needing both the index and the value during a loop, enumerate()
should be the first tool you reach for.
We’ve now learned a huge amount about lists: how to create them, modify them, and loop through them like a pro. It’s time to combine all these skills into a practical mini-project. In Post #57, we will build a functional command-line to-do list application.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com