The enumerate() function in Python is used to add a counter (index) to an iterable (like a list, tuple, or string). It returns an enumerate object, which can be converted into a list of tuples, where each tuple contains an index and the corresponding item from the iterable.
enumerate(iterable, start=0)
iterable: The sequence to be iterated over (e.g., list, tuple, string).
start (optional): The starting index (default is 0).
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
print(f"Index: {index}, Fruit: {fruit}")
Output:
Index: 0, Fruit: apple
Index: 1, Fruit: banana
Index: 2, Fruit: cherry
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits, start=1):
print(f"Index: {index}, Fruit: {fruit}")
Output:
Index: 1, Fruit: apple
Index: 2, Fruit: banana
Index: 3, Fruit: cherry
names = ["Alice", "Bob", "Charlie"]
enumerated_list = list(enumerate(names))
print(enumerated_list)
Output:
[(0, 'Alice'), (1, 'Bob'), (2, 'Charlie')]
Avoids Manual Index Tracking: No need to use range(len(iterable)).
Readable and Concise: Makes loops cleaner and easier to understand.
Works with Any Iterable: Can be used with lists, tuples, strings, etc.
When you use enumerate(), it returns an enumerate object, which is an iterator. You can see what it looks like by printing it directly.
fruits = ['apple', 'banana', 'cherry']
enum_obj = enumerate(fruits)
print(enum_obj) # Printing the enumerate object
print(list(enum_obj)) # Converting it to a list to see its contents
Output:
<enumerate object at 0x7f8b3c0d5c80>
[(0, 'apple'), (1, 'banana'), (2, 'cherry')]
The first print(enum_obj) shows the memory address of the enumerate object.
The second print(list(enum_obj)) converts the object into a list of tuples so we can see its contents.
The reason an enumerate object does not have a meaningful __repr__ or __str__ is because it is an iterator, not a container like a list or tuple. Let's break it down:
An enumerate object is a generator-like iterator that lazily produces values as you iterate over it. It does not store values in memory, so it does not make sense to print all the values upfront.
Example:
fruits = ["apple", "banana", "cherry"]
enum_obj = enumerate(fruits)
print(enum_obj) # Just shows the memory location
print(next(enum_obj)) # (0, 'apple')
print(next(enum_obj)) # (1, 'banana')
Output:
<enumerate object at 0x7f8b3c0d5c80>
(0, 'apple')
(1, 'banana')
Since it produces values on demand, enumerate does not have a built-in __repr__ that prints all its contents.
This behavior is similar to map(), zip(), and filter(), which also return iterators and do not store all their values in memory.
Example:
nums = [1, 2, 3]
map_obj = map(lambda x: x * 2, nums)
print(map_obj) # Shows memory location
print(list(map_obj)) # Converts it to a list
Output:
<map object at 0x7f8b3c0d5c80>
[2, 4, 6]
If you want to see the contents of an enumerate object, you must convert it to a list:
fruits = ["apple", "banana", "cherry"]
enum_obj = enumerate(fruits)
print(list(enum_obj)) # [(0, 'apple'), (1, 'banana'), (2, 'cherry')]
Let's create a custom class that mimics enumerate but includes a __repr__ method to display its contents.
class MyEnumerate:
def __init__(self, iterable, start=0):
self.iterable = iter(iterable) # Convert to iterator
self.index = start
def __iter__(self):
return self
def __next__(self):
item = next(self.iterable) # Get next item
result = (self.index, item)
self.index += 1
return result
def __repr__(self):
return f"MyEnumerate(start={self.index}, iterable={list(self.iterable)})"
# Example usage
fruits = ["apple", "banana", "cherry"]
enum_obj = MyEnumerate(fruits)
print(enum_obj) # Calls __repr__
print(next(enum_obj)) # Get first item
print(next(enum_obj)) # Get second item
print(enum_obj) # Calls __repr__ again
MyEnumerate(start=0, iterable=['apple', 'banana', 'cherry'])
(0, 'apple')
(1, 'banana')
MyEnumerate(start=2, iterable=['cherry']) # Remaining items
__init__ – Stores the iterable and converts it to an iterator.
__iter__ – Makes the object an iterator.
__next__ – Returns (index, value) and increments the index.
__repr__ – Converts the remaining items to a list for display.
⚠ Limitation:
Since enumerate() is an iterator, once an item is consumed, it's gone! Our __repr__ only shows unconsumed values, not the full original list.