Choosing between direct iteration and enumerate() depends on one question: do you need the index of each item?
Basic Iteration for Values Only
When you only need the items themselves, iterate directly over the collection:
fruits = ["Apple", "Banana", "Cherry"]
for fruit in fruits:
print(fruit)This is the cleanest and most Pythonic approach when position doesn't matter.
Using enumerate() for Index and Value
When you need both the position and the item, enumerate() provides both efficiently:
fruits = ["Apple", "Banana", "Cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")The function returns tuples of (index, item) that you unpack directly in the loop.
Custom Starting Index
By default, indexing starts at 0. Use the start parameter to change this:
fruits = ["Apple", "Banana", "Cherry"]
for rank, fruit in enumerate(fruits, start=1):
print(f"Rank {rank}: {fruit}")This is particularly useful for displaying numbered lists to users.
Avoid the range(len()) Anti-Pattern
Coming from C or Java, developers often write index-based loops manually:
fruits = ["Apple", "Banana", "Cherry"]
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")Practical Use Cases
Modifying Based on Position
items = ["first", "second", "third"]
result = []
for i, item in enumerate(items):
if i == 0:
result.append(item.upper())
else:
result.append(item)
print(result) # ['FIRST', 'second', 'third']Finding Item Positions
scores = [85, 92, 78, 92, 88]
max_score = max(scores)
positions = [i for i, score in enumerate(scores) if score == max_score]
print(f"Max score {max_score} at positions: {positions}")Processing with Context
lines = ["Header", "Data 1", "Data 2", "Footer"]
for i, line in enumerate(lines):
if i == 0:
print(f"[HEADER] {line}")
elif i == len(lines) - 1:
print(f"[FOOTER] {line}")
else:
print(f"[DATA] {line}")Enumerating Other Iterables
enumerate() works with any iterable, not just lists:
for i, char in enumerate("ABC"):
print(f"{i}: {char}")
data = {"a": 1, "b": 2}
for i, key in enumerate(data):
print(f"{i}: {key}")
with open("data.txt") as f:
for line_num, line in enumerate(f, start=1):
print(f"Line {line_num}: {line.strip()}")Quick Reference
| Pattern | Use When |
|---|---|
for item in iterable |
You only need values |
for i, item in enumerate(iterable) |
You need position and value |
for i, item in enumerate(iterable, start=1) |
You need 1-based numbering |
Summary
Use direct iteration (for x in list) when you only need values. Use enumerate() when you need positions. Never manually track indices with i = 0; i += 1 or use range(len()) when iterating over sequences. The enumerate() function is cleaner, less error-prone, and clearly communicates your intent.