Background:
The enumerate() function was introduced in Python 2.3 and is now the standard way to access both an element and its index simultaneously when iterating over collections. Before enumerate(), programmers often created their own counters or used the range(len(sequence)) function, which was inconvenient and less readable.
Problem:
A regular for loop only iterates over values. To access the index, range(len(...)) is often used, which does not work for all iterable objects (e.g., generators, strings, and tuples of variable length, as well as during filtering). This leads to errors and complicates the code.
Solution:
enumerate() returns pairs (index, element), allowing you to get the index of the current element even for non-standard collections or filtered generators. The function takes an optional second argument — the starting value of the counter.
Code example:
words = ['apple', 'banana', 'cherry'] for idx, word in enumerate(words, 1): print(f"{idx}: {word}") # Output: # 1: apple # 2: banana # 3: cherry
Key features:
Why do functions often use enumerate instead of range(len(seq))?
Answer: range(len(seq)) only works for sequences with index access and does not account for changes in length during iteration. Additionally, it is less readable and may run slower or fail altogether for generators. enumerate() provides safe access to index-value pairs for any iterable collection.
Code example:
# Does not work with a generator: gen = (x for x in range(5)) for i in range(len(gen)): print(i) # Error: the generator has no length
Can you use enumerate to modify elements of a list during iteration?
Answer: Yes, but you need to iterate over the indices to update values. Otherwise, if you iterate only over values, you will alter a copy of the object, not the original.
Code example:
nums = [1, 2, 3] for idx, val in enumerate(nums): nums[idx] = val * 2 # nums = [2, 4, 6]
What will enumerate return if given an object that changes during iteration?
Answer: If the collection changes during iteration (for example, elements are deleted), behavior can be unexpected, because enumerate relies on an internal iterator that can get confused. Therefore, modifying the collection during iteration is not recommended.
range(len(...)) for objects without length or for those whose length may change.Negative case
A programmer iterates over a list using range(len(list)) and removes elements on the fly. The result — indices get messed up, and some elements are skipped.
Pros:
Cons:
Positive case
enumerate() is used, and a new list of needed elements is formed or the value is changed by index, but the size of the list does not change during the loop.
Pros:
Cons: