Ei vielä käännetty
Tätä sivua ei ole vielä käännetty suomeksi, joten se näytetään englanniksi. Auta kääntämään
enumerate() Function Complexity¶
The enumerate() function returns an iterator that produces tuples of (index, item) from an iterable.
Complexity Analysis¶
| Case | Time | Space | Notes |
|---|---|---|---|
| Creating iterator | O(1) | O(1) | Just creates iterator object |
| Consuming iterator | O(n) | O(1) | n = items iterated; yields one at a time |
| With custom start | O(n) | O(1) | start parameter doesn't change complexity |
Note: enumerate() returns an iterator that yields tuples lazily. Space is O(1) because it doesn't store all tuples in memory. Converting to list with list(enumerate(x)) is O(n) space.
Basic Usage¶
Simple Enumeration¶
# O(1) - creates iterator
items = ['a', 'b', 'c']
enumerated = enumerate(items) # Iterator
# O(n) - consumed when needed
for index, item in enumerated:
print(index, item)
# 0 a
# 1 b
# 2 c
# Convert to list - O(n) time and space
result = list(enumerate(items))
# [(0, 'a'), (1, 'b'), (2, 'c')]
Custom Start Index¶
# O(1) - creates iterator
items = ['a', 'b', 'c']
enumerated = enumerate(items, start=1)
# O(n) - consumed
result = list(enumerated)
# [(1, 'a'), (2, 'b'), (3, 'c')]
# Works with any start value
result = list(enumerate(items, start=10))
# [(10, 'a'), (11, 'b'), (12, 'c')]
Performance Patterns¶
Lazy Evaluation¶
# O(1) - creates iterator, doesn't process yet
big_list = range(10**9)
enumerated = enumerate(big_list)
# O(n) - only when you consume
for i, item in enumerate(big_list):
print(i, item)
if i >= 10:
break # O(10) - stops early
# vs list comprehension
result = [(i, x) for i, x in enumerate(range(10**9))] # O(10^9)!
Nested Enumeration¶
# O(n*m*k) - enumerate nested structures
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# O(n*m) - enumerate rows and columns
for i, row in enumerate(matrix):
for j, item in enumerate(row):
print(f"[{i}][{j}] = {item}")
Common Patterns¶
Iterating with Index¶
# ✅ O(n) - preferred way
items = ['a', 'b', 'c', 'd', 'e']
for index, item in enumerate(items):
print(index, item)
# ❌ O(n) but less Pythonic
for i in range(len(items)):
print(i, items[i])
# ❌ O(n) with unnecessary zip
for i, item in zip(range(len(items)), items):
print(i, item)
Filtering with Index¶
# O(n) - enumerate and filter
items = ['a', 'b', 'c', 'd', 'e']
result = [item for i, item in enumerate(items) if i % 2 == 0]
# ['a', 'c', 'e']
# Get only indices
indices = [i for i, item in enumerate(items) if 'a' in item]
# [0]
Building New Structure¶
# O(n) - enumerate to create dict
items = ['apple', 'banana', 'cherry']
item_dict = {i: item for i, item in enumerate(items)}
# {0: 'apple', 1: 'banana', 2: 'cherry'}
# With custom start
item_dict = {i: item for i, item in enumerate(items, start=1)}
# {1: 'apple', 2: 'banana', 3: 'cherry'}
Working with Multiple Iterables¶
Parallel Iteration with Index¶
# O(n) - enumerate with zip
names = ['Alice', 'Bob', 'Charlie']
ages = [30, 25, 35]
for i, (name, age) in enumerate(zip(names, ages)):
print(f"{i}: {name} is {age}")
# 0: Alice is 30
# 1: Bob is 25
# 2: Charlie is 35
Nested Structures¶
# O(n*m*k) - multiple levels of enumeration
data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for i, row in enumerate(data):
for j, item in enumerate(row):
print(f"[{i}][{j}] = {item}")
Advanced Patterns¶
Enumerate with Custom Index¶
# O(n) - enumerate with offset
items = ['a', 'b', 'c', 'd', 'e']
for index, item in enumerate(items, start=100):
print(index, item)
# 100 a
# 101 b
# ... etc
Finding Position¶
# O(n) - find position of element
items = ['apple', 'banana', 'cherry', 'date']
target = 'cherry'
for index, item in enumerate(items):
if item == target:
position = index
break
# position = 2
# Alternative: use index() method
position = items.index(target) # O(n) - same complexity
Conditional Enumeration¶
# O(n) - enumerate with filter
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Only enumerate even items
for index, item in enumerate(items):
if item % 2 == 0:
print(index, item)
# 1 2
# 3 4
# ... etc
Comparison with Alternatives¶
enumerate vs range(len(...))¶
# ✅ enumerate - preferred, more Pythonic
items = ['a', 'b', 'c']
for i, item in enumerate(items):
print(i, item)
# ❌ range(len(...)) - less readable
for i in range(len(items)):
print(i, items[i])
# Both O(n), enumerate is clearer
enumerate vs zip with range¶
# ✅ enumerate - simpler and faster
items = ['a', 'b', 'c']
for i, item in enumerate(items):
process(i, item)
# ❌ zip with range - unnecessary overhead
for i, item in zip(range(len(items)), items):
process(i, item)
# Both O(n), enumerate is more efficient
enumerate vs Index Method¶
# If finding position of one element
items = ['a', 'b', 'c', 'd', 'e']
target = 'c'
# O(n) - enumerate
for i, item in enumerate(items):
if item == target:
print(i)
break
# O(n) - index method
print(items.index(target))
# If finding multiple positions
# enumerate is more efficient - single pass
# If finding one - index() is clearer
Edge Cases¶
Empty Iterable¶
# O(1) - creates empty iterator
result = list(enumerate([]))
# []
for i, item in enumerate([]):
print(i, item) # Never executes
Single Item¶
# O(1) - creates iterator with one element
result = list(enumerate(['a']))
# [(0, 'a')]
Large Start Value¶
# O(1) - start value doesn't affect complexity
result = list(enumerate([1, 2, 3], start=10**9))
# [(1000000000, 1), (1000000001, 2), (1000000002, 3)]
Generators¶
# O(n) - enumerate can consume generators
def generator():
yield 1
yield 2
yield 3
for i, value in enumerate(generator()):
print(i, value)
# 0 1
# 1 2
# 2 3
Performance Considerations¶
Memory Efficiency¶
# ✅ Iterator - memory efficient
big_list = range(10**9)
for i, item in enumerate(big_list):
if i < 10:
print(item)
# Only iterates 10 items
# ❌ List creation - uses memory
indices_items = list(enumerate(range(10**9))) # Huge memory!
Speed Comparison¶
import timeit
items = list(range(1000))
# Time for enumerate
t1 = timeit.timeit(lambda: [x for i, x in enumerate(items)], number=10000)
# Time for range(len(...))
t2 = timeit.timeit(lambda: [items[i] for i in range(len(items))], number=10000)
# enumerate is generally faster due to optimizations
Best Practices¶
✅ Do:
- Use
enumerate()when you need both index and item - Use
enumerate(iterable, start=1)for 1-based indexing - Use
enumerate()withbreakfor early exit - Use
enumerate()for lazy evaluation with large datasets
❌ Avoid:
- Using
range(len(...))whenenumerate()is clearer - Using
zip(range(len(...)), iterable)- useenumerate()instead - Forgetting that
enumerate()returns an iterator - Creating intermediate lists unnecessarily
Related Functions¶
- zip() - Combine multiple iterables
- range() - Generate number sequences
- iter() - Create iterators
- next() - Get next item from iterator
Version Notes¶
- Python 2.x:
enumerate()available, works similarly - Python 3.x: Same behavior and performance
- Python 3.8+: Optimizations may improve performance but O(n) guaranteed