Iterate a list with indexes
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Iterating over a list with indexes is a basic Python task, but there is a right way and several weaker alternatives. The idiomatic solution is usually enumerate, which gives you both position and value without manual counter management. Knowing when to use enumerate, when to use range, and when to avoid indexes entirely makes loop code clearer and less error-prone.
Use enumerate as the Default Pattern
For most read-only loops where you need both the item and its position, use enumerate.
This is preferred over manual index tracking because it is explicit and avoids bookkeeping bugs.
You can also start counting from a custom value:
That is useful for user-facing numbering where counting should begin at 1 instead of 0.
Use range(len(...)) Only When You Need Index-Based Access
Sometimes the loop logic really depends on indexing, such as looking at neighboring elements or mutating the list by position.
This is valid, but it is more verbose than enumerate. Use it when the index itself is part of the algorithm, not just because it feels familiar.
For example, comparing adjacent elements naturally uses index arithmetic:
In this kind of loop, range is the correct tool.
Modify List Elements by Index Safely
If you need to replace values inside the same list, loop by index rather than by element value.
This works because you are writing back to the original list by position.
Be careful with structural changes such as inserting or removing elements while iterating. That can shift indexes and produce hard-to-debug behavior. If you need heavy modification, build a new list instead.
Avoid Indexes When You Do Not Need Them
A lot of code uses indexes unnecessarily. If you only need the values, loop over the values directly.
This is simpler than introducing an index you never use.
Likewise, if you need parallel iteration across two sequences, zip is often clearer than managing indexes manually.
Use indexes when they add value, not by default.
Combine Index Logic with Conditions
Index-aware loops are often useful for formatting and positional rules.
This pattern is common in reporting, alternating row styles, and sequence-based algorithms.
Iterating Nested Lists with Indexes
For tables or grid-like data, nested enumerate calls keep both row and column positions available.
This is much clearer than manually incrementing counters at two levels.
Performance and Readability Tradeoff
In normal application code, readability matters more than tiny loop micro-optimizations. enumerate is both idiomatic and efficient enough for most workloads.
If you are working in a tight numerical loop, measure before changing style for performance reasons. In many cases, the surrounding algorithm matters far more than the difference between enumerate and range(len(...)).
Common Pitfalls
One common mistake is using range(len(items)) when only the values are needed. That makes code noisier without adding useful information.
Another issue is modifying list structure while iterating with indexes. Removing or inserting items can invalidate index assumptions mid-loop.
A third mistake is shadowing the meaning of the index variable by reusing it for unrelated logic inside the loop body.
Summary
- Use
enumerateas the standard way to iterate over a list with indexes in Python. - Use
range(len(...))only when you genuinely need index arithmetic or positional writes. - Iterate over values directly when indexes are unnecessary.
- Prefer building a new list over mutating structure during indexed iteration.
- Choose the loop form that matches the algorithm, not just habit.
Related reading
- Iterate through binary search tree to find all leaves
- Iterating over a Binary Tree with O1 Auxiliary Space
- Iterating over dictionaries using 'for' loops
- Iterating over every two elements in a list
- Iterate an iterator by chunks of n in Python?
- Iterate over model instance field names and values in template
- Iterating Through a Dictionary in Swift
- Iterating through a list in reverse order in java

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.