enumerate()
enumerate() in Python
Learn how to access both the position and value of each item while iterating over a Python iterable.
While processing a list, tuple, string, or another iterable, programmers often need both the current item and its position. One approach is to create and update a counter manually.
Python provides the built-in enumerate() function
for this purpose. It produces pairs containing a counter and the
corresponding item from the iterable.
enumerate(), how to unpack its values, how to select
a custom starting number, and how to use it with different
iterable objects.
Prerequisites
What You Should Know
- Python variables and basic data types
- Lists, tuples, strings, and dictionaries
- Using
forloops - Tuple creation and tuple unpacking
- Using
ifconditions - Basic understanding of iterable objects
What is enumerate()?
enumerate() is a built-in Python function that
accepts an iterable and returns an enumerate object.
During iteration, the enumerate object supplies pairs containing the current count and the corresponding value from the original iterable.
Think of enumerate() as automatic serial numbering
Imagine writing numbers beside items in a checklist.
enumerate() automatically supplies those
numbers while preserving access to each original item.
Syntax
enumerate(iterable, start=0)
| Parameter | Requirement | Purpose |
|---|---|---|
iterable
|
Required | Supplies the values to enumerate. |
start
|
Optional | Defines the first counter value. Its default value is zero. |
Basic enumerate() Example
Use enumerate() to display the position and value
of each programming language:
languages = [
"Python",
"Java",
"C#",
"JavaScript"
]
for index, language in enumerate(languages):
print(index, language)
Output:
0 Python
1 Java
2 C#
3 JavaScript
On every iteration, Python unpacks the generated pair into
index and language.
What Does enumerate() Return?
Calling enumerate() creates an enumerate object.
languages = ["Python", "Java", "C#"]
result = enumerate(languages)
print(result)
print(type(result))
Possible output:
<enumerate object at 0x...>
<class 'enumerate'>
Convert enumerate() to a List
Convert an enumerate object to a list to view all generated index-value pairs:
languages = [
"Python",
"Java",
"C#"
]
result = list(enumerate(languages))
print(result)
Output:
[(0, 'Python'), (1, 'Java'), (2, 'C#')]
Each element in the resulting list is a tuple containing the counter and the original value.
Set a Custom Starting Number
The optional start parameter changes the first
counter value.
languages = [
"Python",
"Java",
"C#"
]
for position, language in enumerate(
languages,
start=1
):
print(position, language)
Output:
1 Python
2 Java
3 C#
start=1 for serial numbers, rankings,
user-facing menus, and other situations where counting from one
is more natural.
Manual Counter vs enumerate()
Using a Manual Counter
languages = [
"Python",
"Java",
"C#"
]
position = 1
for language in languages:
print(position, language)
position += 1
Using enumerate()
languages = [
"Python",
"Java",
"C#"
]
for position, language in enumerate(
languages,
start=1
):
print(position, language)
Manual Counter
- Requires a separate counter variable
- Requires manual incrementing
- The increment may be forgotten
- Counter logic is mixed with business logic
enumerate()
- Provides the counter automatically
- Supports a custom starting value
- Keeps iteration logic concise
- Clearly communicates the need for position and value
Retrieve Pairs with next()
An enumerate object is an iterator. The built-in
next() function retrieves its next pair.
languages = [
"Python",
"Java",
"C#"
]
language_iterator = enumerate(
languages,
start=1
)
print(next(language_iterator))
print(next(language_iterator))
print(next(language_iterator))
Output:
(1, 'Python')
(2, 'Java')
(3, 'C#')
enumerate() Object Exhaustion
An enumerate object is consumed as its pairs are requested. After all pairs are produced, the same object is exhausted.
languages = ["Python", "Java"]
numbered_languages = enumerate(
languages,
start=1
)
print(list(numbered_languages))
print(list(numbered_languages))
Output:
[(1, 'Python'), (2, 'Java')]
[]
Use enumerate() with a List
products = [
"Laptop",
"Keyboard",
"Mouse",
"Monitor"
]
for serial_number, product in enumerate(
products,
start=1
):
print(
f"{serial_number}. {product}"
)
Output:
1. Laptop
2. Keyboard
3. Mouse
4. Monitor
Use enumerate() with a Tuple
departments = (
"Finance",
"Human Resources",
"Information Technology"
)
for index, department in enumerate(departments):
print(index, department)
Output:
0 Finance
1 Human Resources
2 Information Technology
Use enumerate() with a String
A string is iterable, so enumerate() can provide
the position of each character.
language = "Python"
for index, character in enumerate(language):
print(index, character)
Output:
0 P
1 y
2 t
3 h
4 o
5 n
Find All Matching Positions
Locate every position where a character appears:
text = "programming"
positions = [
index
for index, character in enumerate(text)
if character == "m"
]
print(positions)
Output:
[6, 7]
Unlike str.index(), this pattern can collect all
matching positions rather than only one match.
Use enumerate() with a Dictionary
Iterating directly over a dictionary produces its keys:
employee = {
"name": "Amina",
"department": "IT",
"active": True
}
for index, key in enumerate(
employee,
start=1
):
print(index, key)
Output:
1 name
2 department
3 active
Enumerate Dictionary Items
Use dictionary.items() when both the dictionary key
and value are required.
employee = {
"name": "Amina",
"department": "IT",
"active": True
}
for position, item in enumerate(
employee.items(),
start=1
):
key, value = item
print(
position,
key,
value
)
Output:
1 name Amina
2 department IT
3 active True
Nested unpacking can make the loop more concise:
for position, (key, value) in enumerate(
employee.items(),
start=1
):
print(position, key, value)
Use enumerate() with a Set
A set is iterable, so it can be used with
enumerate(). However, sets do not represent a
positional sequence.
skills = {
"Python",
"SQL",
"Git"
}
for count, skill in enumerate(
skills,
start=1
):
print(count, skill)
Use enumerate() with a Generator
squares = (
number ** 2
for number in range(1, 6)
)
for position, square in enumerate(
squares,
start=1
):
print(position, square)
Output:
1 1
2 4
3 9
4 16
5 25
Filter by Position
Use the generated index inside a condition. The following example processes values at even-numbered indexes:
values = [
"A",
"B",
"C",
"D",
"E",
"F"
]
for index, value in enumerate(values):
if index % 2 == 0:
print(index, value)
Output:
0 A
2 C
4 E
Filter by Item Value
scores = [
72,
35,
91,
28,
64
]
for position, score in enumerate(
scores,
start=1
):
if score >= 40:
print(
f"Student {position}: Passed"
)
Output:
Student 1: Passed
Student 3: Passed
Student 5: Passed
Update List Values by Index
The index provided by enumerate() can be used to
update values in a mutable sequence.
prices = [
100,
250,
500
]
for index, price in enumerate(prices):
prices[index] = round(
price * 1.10,
2
)
print(prices)
Output:
[110.0, 275.0, 550.0]
Find the Position of a Matching Item
products = [
"Laptop",
"Keyboard",
"Mouse",
"Monitor"
]
target_product = "Mouse"
found_position = None
for position, product in enumerate(
products,
start=1
):
if product == target_product:
found_position = position
break
print(found_position)
Output:
3
Create a Numbered Menu
menu_options = [
"Create Record",
"Update Record",
"View Record",
"Exit"
]
print("Application Menu")
for option_number, option in enumerate(
menu_options,
start=1
):
print(
f"{option_number}. {option}"
)
Output:
Application Menu
1. Create Record
2. Update Record
3. View Record
4. Exit
Enumerate a Nested List
Use nested enumerate() calls to obtain row and column
positions.
matrix = [
[10, 20, 30],
[40, 50, 60]
]
for row_index, row in enumerate(matrix):
for column_index, value in enumerate(row):
print(
row_index,
column_index,
value
)
Output:
0 0 10
0 1 20
0 2 30
1 0 40
1 1 50
1 2 60
Number Lines from a File
The start parameter is useful when displaying
human-readable line numbers.
with open(
"notes.txt",
mode="r",
encoding="utf-8"
) as notes_file:
for line_number, line in enumerate(
notes_file,
start=1
):
print(
line_number,
line.rstrip()
)
Each file line is processed one at a time and accompanied by its corresponding line number.
Use enumerate() in List Comprehension
Create formatted labels containing serial numbers and values:
departments = [
"Finance",
"Sales",
"Information Technology"
]
numbered_departments = [
f"{number}. {department}"
for number, department in enumerate(
departments,
start=1
)
]
print(numbered_departments)
Output:
['1. Finance', '2. Sales', '3. Information Technology']
Combine enumerate() with zip()
zip() combines corresponding values from multiple
iterables. enumerate() can add a serial number to
every combined record.
names = [
"Amina",
"Rahul",
"David"
]
departments = [
"IT",
"Finance",
"Sales"
]
for employee_number, employee_data in enumerate(
zip(names, departments),
start=1
):
name, department = employee_data
print(
employee_number,
name,
department
)
Output:
1 Amina IT
2 Rahul Finance
3 David Sales
Nested unpacking can also be used:
for employee_number, (name, department) in enumerate(
zip(names, departments),
start=1
):
print(
employee_number,
name,
department
)
Practical Example: Number Customer Orders
orders = [
{
"order_number": "ORD-101",
"amount": 750
},
{
"order_number": "ORD-102",
"amount": 1500
},
{
"order_number": "ORD-103",
"amount": 2200
}
]
for serial_number, order in enumerate(
orders,
start=1
):
print(
f"{serial_number}. "
f"{order['order_number']} - "
f"{order['amount']}"
)
Output:
1. ORD-101 - 750
2. ORD-102 - 1500
3. ORD-103 - 2200
The start Value Is a Counter
The starting value does not change the underlying iterable or its actual sequence indexes.
colors = [
"Red",
"Green",
"Blue"
]
for count, color in enumerate(
colors,
start=100
):
print(count, color)
Output:
100 Red
101 Green
102 Blue
Common Mistakes
Forgetting to Unpack the Pair
Each iteration produces a pair containing the count and item.
for index, value in enumerate(values):
Expecting Counting to Start at One
The default counter begins at zero.
start=1 when user-facing numbering should
begin at one.
Confusing Counter with Actual List Index
A custom starting value changes the generated count but not the underlying list indexes.
Trying to Reuse a Consumed enumerate Object
An enumerate object is an iterator and becomes exhausted.
enumerate() again when another iteration is
required.
Using enumerate() When the Position Is Unnecessary
Adding an unused counter makes the loop more complicated.
for item in iterable loop when only
the item is required.
When to Use enumerate()
Good Use Cases
- Displaying serial numbers beside values
- Creating numbered menus
- Processing file lines with line numbers
- Updating list values using their indexes
- Finding all positions of matching values
- Processing rows and columns in nested lists
- Adding record numbers to combined zip results
- Replacing manually maintained counters
When enumerate() Is Unnecessary
Use a Simpler Loop When
- Only the item value is required.
- The position is never referenced inside the loop.
- You are iterating over dictionary items and do not need an additional serial number.
- A direct membership test can solve the problem without iteration.
Best Practices
Recommended Practices
-
Use descriptive variable names such as
index,position, orline_number. -
Use
start=1for human-readable numbering. - Keep the default start when the value represents a zero-based sequence index.
- Use nested unpacking carefully when enumerating dictionary items or zipped values.
- Avoid structural modification of a list during iteration.
-
Do not use
enumerate()when the counter is unnecessary.
Hands-On Practice
Practice Exercises
- Print a numbered list of five programming languages.
- Display every character and its position in a string.
- Find all indexes where a particular number appears in a list.
- Create a menu whose numbering begins at one.
- Increase every price in a list by five percent using its index.
- Enumerate dictionary items and print serial number, key, and value.
-
Use nested
enumerate()to display matrix coordinates. -
Combine
enumerate()andzip()to display numbered employee records.
Knowledge Check
What does enumerate() return?
It returns an enumerate object that produces pairs containing a count and an item from the iterable.
What is the default starting value?
The default starting value is zero.
How do you start counting at one?
for position, item in enumerate(
values,
start=1
):
print(position, item)
Can enumerate() work with a string?
Yes. A string is iterable, so its characters can be enumerated.
Does start=1 change the actual list indexes?
No. It changes only the generated counter values.
enumerate() Quick Reference
# Basic enumeration
for index, item in enumerate(iterable):
print(index, item)
# Start counting at one
for position, item in enumerate(
iterable,
start=1
):
print(position, item)
# Convert to a list of tuples
numbered_items = list(
enumerate(iterable)
)
# Retrieve one pair
iterator = enumerate(iterable)
index, item = next(iterator)
# Enumerate dictionary items
for position, (key, value) in enumerate(
dictionary.items(),
start=1
):
print(position, key, value)
# Enumerate zipped values
for position, (first, second) in enumerate(
zip(first_values, second_values),
start=1
):
print(position, first, second)
# Create numbered labels
labels = [
f"{position}. {item}"
for position, item in enumerate(
iterable,
start=1
)
]
# Find matching indexes
indexes = [
index
for index, item in enumerate(iterable)
if item == target
]
Summary
What You Learned
-
enumerate()provides a counter and item during iteration. - The default counter begins at zero.
-
The
startargument sets a custom initial counter value. - An enumerate object produces count-item tuples.
- Tuple unpacking provides direct access to both generated values.
-
enumerate()works with lists, tuples, strings, dictionaries, generators, and other iterables. - An enumerate object becomes exhausted after its values are consumed.
- A custom counter does not change the original sequence indexes.
Key Takeaway
Use enumerate() whenever a loop requires both an item's position and its value. It removes manual counter management, supports custom starting values, and makes indexed iteration clearer and less error-prone.