Iterating over data is one of the most fundamental operations in Python — it means stepping through each element of a collection (list, tuple, string, dictionary, set, file, range, or any iterable) one by one to process, transform, filter, aggregate, or display them. The for loop is the cleanest, most Pythonic way to do this, but Python also offers manual iteration with next(), generators, comprehensions, and tools like enumerate(), zip(), and itertools. In 2026, iteration powers everything from simple scripts to massive data pipelines in pandas, Polars, and streaming applications.
Here’s a complete, practical guide to iterating over data: basic for loops, common iterables, advanced patterns (enumerate, zip, file iteration), and modern best practices with type hints, error handling, and memory efficiency.
The classic for loop is simple and readable — it works on any iterable and automatically stops when done.
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print(num * 2)
# Output:
# 2
# 4
# 6
# 8
# 10
Strings iterate character by character — great for text processing or validation.
message = "Hello, world!"
for char in message:
if char.isalpha():
print(char.upper(), end="") # HELLOWORLD
Dictionaries iterate over keys by default — use .items() for key-value pairs (most common), .keys() for keys, or .values() for values only.
person = {"name": "Alice", "age": 30, "city": "New York"}
# Key-value pairs (best practice)
for key, value in person.items():
print(f"{key.capitalize()}: {value}")
# Output:
# Name: Alice
# Age: 30
# City: New York
Files are iterables — loop over lines directly for memory-efficient processing of huge files (logs, CSVs, JSONL).
with open("log.txt", "r", encoding="utf-8") as f:
for line_num, line in enumerate(f, start=1):
clean = line.strip()
if "ERROR" in clean:
print(f"Error on line {line_num}: {clean}")
Real-world pattern: parallel iteration with zip() — combine related sequences (columns, coordinates, paired data) without manual indexing.
names = ["Alice", "Bob", "Charlie"]
ages = [30, 25, 35]
cities = ["New York", "Chicago", "Seattle"]
for name, age, city in zip(names, ages, cities):
print(f"{name} ({age}) from {city}")
# Output:
# Alice (30) from New York
# Bob (25) from Chicago
# Charlie (35) from Seattle
Best practices make iteration clean, efficient, and safe. Prefer for item in iterable over index-based loops — more readable and faster. Use enumerate(start=1) for user-facing numbering — 0-based is fine internally. Use .items() for dictionaries — clearer than dict[key] lookups. Avoid modifying the iterable inside the loop — collect changes in a new list to prevent skips or errors. Use comprehensions for simple transformations — they’re often faster and more Pythonic than for + append(). Modern tip: for very large data, use generators (yield) or Polars lazy frames — they iterate without loading everything into memory. In production, wrap iteration over external data (files, APIs, databases) in try/except — handle bad items gracefully without crashing the loop. Combine with zip(), enumerate(), and itertools for parallel, indexed, or sliced iteration.
Iteration is how Python turns collections into results — one item at a time, cleanly and efficiently. In 2026, master for loops, enumerate(), zip(), .items(), comprehensions, and safe error handling. Whether you’re processing small lists or massive files, iteration is your most used tool — make it readable, robust, and Pythonic.
Next time you have data — lists, files, dictionaries, or streams — reach for a for loop. It’s Python’s simplest, most powerful way to work through items one at a time.