Think of a list as a conveyor belt carrying items to your workstation. Sometimes, you need both the item and its position on that belt—like printing line numbers in a report or matching names with scores. The old habit is reaching for
range(len(my_list)) to count manually. That works, but it makes your code noisier and harder to read.enumerate()
tasks = ['write', 'test', 'deploy']
for i, t in enumerate(tasks):
print(f'{i}: {t}')enumerate wraps your list into pairs of (index, value). You unpack them directly in the loop header. This is cleaner than manual counting because Python handles the indexing for you.tasks = ['write', 'test', 'deploy']
for i, t in enumerate(tasks, start=1):
print(f'{i}. {t}')The
start argument lets you change where counting begins. This is useful for human-facing output, like numbered lists in a UI or report.zip()
names = ['Ada', 'Grace']
scores = [92, 85]
for n, s in zip(names, scores):
print(f'{n} scored {s}')zip glues two lists together element by element. It stops when the shorter list runs out, so you never hit an IndexError. This makes parallel iteration safer and cleaner than manual indexing.You now have the tools to write functions like
numbered(items) using enumerate, or pair(names, scores) using zip. These patterns show up constantly: numbered receipts, paired sensor readings, ranked leaderboards. Your code will be shorter and less error-prone.