Control Flow
Enumerate
Getting index and value in loops
Interview: Tests knowledge of Pythonic idioms — interviewers look for enumerate over range(len())
The enumerate() built-in adds a counter to any iterable and returns an iterator of (index, value) tuples. It's the Pythonic way to get both the index and value when iterating, replacing the anti-pattern of range(len()).
Basic Usage
- Signature:
enumerate(iterable, start=0) - Returns: An iterator (lazy, memory-efficient) yielding
(index, element)tuples - Works with any iterable: Lists, strings, dicts, files, generators, custom iterables
- start parameter: Begin counting from any value (common use: 1-based indexing)
Why enumerate() Over range(len())
- More readable: Intent is clear — you want index + value
- Works with generators:
range(len())fails on generators (no len) - No double indexing:
lst[i]inside the loop is unnecessary and error-prone - Works with non-sequence iterables: Files, sets, dict keys, etc.
Advanced Patterns
- Unpacking in comprehension:
{val: i for i, val in enumerate(items)}— creates value-to-index mapping - Parallel with zip:
for i, (a, b) in enumerate(zip(list1, list2)): - Filtering with index:
[v for i, v in enumerate(data) if i % 2 == 0]— keep even-indexed elements - Building dicts:
dict(enumerate(items))— creates index-to-value mapping - Progress tracking: Use enumerate to report progress in long-running loops
Interview Tip
If you catch yourself writing for i in range(len(lst)) and then using lst[i], immediately refactor to enumerate(). This is one of the most common Pythonic code review suggestions.
Under the Hood
enumerate() is implemented in C and is very fast. It's equivalent to this Python generator, but faster:
- It creates an iterator object that wraps the original iterable
- Each call to
next()returns the next(counter, value)tuple - Memory usage is O(1) regardless of the iterable size (it's lazy)
Use Cases
Displaying numbered lists to users (with start=1)
Building index-based mappings from sequences
Filtering elements based on their position
Tracking progress in data processing pipelines
Common Mistakes
Using range(len(lst)) with lst[i] instead of enumerate — less readable and fails for generators
Forgetting to unpack the tuple: writing enumerate(lst) without i, val in the for loop
Using enumerate when you only need values (just iterate directly: for val in lst)
Not knowing enumerate works with any iterable (files, generators), not just lists