Technology  /  Python

🐍 Python 78 guides · updated 2026

From first variable to OOP, generators, and real projects — the language that runs everything from data pipelines to AI agents, taught the practical way.

Iterating Lists, Dictionaries, and Sets in Python: Patterns for Every Collection

Python’s three core collection types — lists, dictionaries, and sets — share the same iteration syntax (for item in collection) but differ significantly in what they expose and what you can rely on. This guide covers the iteration patterns for each, along with the guarantees and limitations that matter in practice.

Lists: Ordered, Indexed, Allows Duplicates

A list preserves insertion order and allows repeated values. Iteration visits elements from index 0 to the end.

Basic Iteration

temperatures = [22.1, 18.5, 25.3, 19.8, 24.0]
for temp in temperatures:
print(f"{temp}°C")

Index and Value Together: enumerate()

When you need the position as well as the value, enumerate() is cleaner than range(len(...)):

products = ["Laptop", "Mouse", "Keyboard", "Monitor"]
for index, product in enumerate(products, start=1):
print(f"{index}. {product}")
# 1. Laptop
# 2. Mouse
# 3. Keyboard
# 4. Monitor

Pairing Two Lists: zip()

names = ["Alice", "Bob", "Carol"]
scores = [91, 84, 88]
for name, score in zip(names, scores):
grade = "A" if score >= 90 else "B"
print(f"{name}: {score} ({grade})")
# Alice: 91 (A)
# Bob: 84 (B)
# Carol: 88 (B)

zip() stops at the shortest list. If your lists might differ in length, use itertools.zip_longest() with a fillvalue.

Iterating in Reverse

steps = ["Preheat oven", "Mix ingredients", "Pour batter", "Bake", "Cool"]
for step in reversed(steps):
print(step)

reversed() works on any sequence with a __reversed__ or __len__ and __getitem__. Lists, tuples, and strings all qualify.

Sorted Iteration

countries = ["Germany", "Australia", "France", "Brazil", "India"]
for country in sorted(countries):
print(country)
# Australia, Brazil, France, Germany, India
# Sorted descending
for country in sorted(countries, reverse=True):
print(country)

sorted() returns a new list — the original is unchanged.

Building Results While Iterating

raw_data = [" Alice ", " 42 ", " Engineering ", " "]
cleaned = [item.strip() for item in raw_data if item.strip()]
print(cleaned) # ['Alice', '42', 'Engineering']

List comprehensions are the idiomatic way to transform and filter in one pass.

Dictionaries: Key-Value Pairs, Ordered Since Python 3.7

Dictionaries iterate over keys by default, but they expose three views: keys(), values(), and items().

Iterating Keys

config = {"host": "localhost", "port": 5432, "dbname": "myapp", "timeout": 30}
# These are identical
for key in config:
print(key)
for key in config.keys():
print(key)

Iterating Values

for value in config.values():
print(value)
# localhost, 5432, myapp, 30

Iterating Key-Value Pairs (Most Common)

for key, value in config.items():
print(f"{key} = {value}")
# host = localhost
# port = 5432
# dbname = myapp
# timeout = 30

This is the most frequently used pattern. The tuple unpacking key, value in the for statement is both concise and explicit.

Conditional Iteration

inventory = {
"apples": 0,
"bananas": 12,
"oranges": 0,
"grapes": 30,
"mangoes": 7,
}
# Items with stock
for product, quantity in inventory.items():
if quantity > 0:
print(f"{product}: {quantity} units")
# bananas: 12 units
# grapes: 30 units
# mangoes: 7 units

Building a Dict From Iteration

words = ["apple", "banana", "cherry", "avocado", "blueberry"]
# Group words by first letter
by_letter = {}
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
print(by_letter)
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

setdefault(key, default) is cleaner than checking if key in dict before appending.

Do Not Modify a Dictionary While Iterating

scores = {"Alice": 88, "Bob": 45, "Carol": 92, "Dave": 51}
# Bug: raises RuntimeError in Python 3
for name in scores:
if scores[name] < 60:
del scores[name] # cannot delete while iterating
# Fix: iterate over a copy of the keys
for name in list(scores.keys()):
if scores[name] < 60:
del scores[name]
print(scores) # {'Alice': 88, 'Carol': 92}

Sets: Unique Elements, No Guaranteed Order

Sets are optimised for membership testing and set operations. Iteration order is not predictable (it depends on hash values and insertion history).

Basic Iteration

tags = {"python", "backend", "data-science", "python", "api"}
# Note: duplicate "python" is silently ignored
for tag in tags:
print(tag)
# Output order is not predictable

Sorted Iteration Over a Set

When order matters, sort the set first:

for tag in sorted(tags):
print(tag)
# api, backend, data-science, python

Set Operations During Iteration

users_online = {"alice", "bob", "carol", "dave"}
premium_users = {"bob", "dave", "eve"}
# Who is online AND premium?
for user in users_online & premium_users: # intersection
print(f"{user} is online and premium")
# Who is online but NOT premium?
for user in sorted(users_online - premium_users): # difference
print(f"{user} is standard tier")

Using Sets to Deduplicate Before Iterating

log_entries = [
"192.168.1.1", "10.0.0.5", "192.168.1.1", "10.0.0.5",
"10.0.0.8", "192.168.1.1"
]
# Process each IP only once
for ip in set(log_entries):
print(f"Processing {ip}")

Choosing the Right Pattern

TaskPattern
Iterate list valuesfor item in my_list
Index + valuefor i, item in enumerate(my_list)
Two lists togetherfor a, b in zip(list1, list2)
Dict keysfor key in my_dict
Dict valuesfor val in my_dict.values()
Dict key-value pairsfor k, v in my_dict.items()
Set (unordered)for item in my_set
Set (sorted)for item in sorted(my_set)
Transform list[f(x) for x in my_list]
Filter list[x for x in my_list if condition]
Reverse listfor item in reversed(my_list)

Common Pitfalls

Expecting sets to be ordered. They are not. Always sort if order matters.

Modifying a collection while iterating. Iterate over list(collection) or a copy when you need to delete items during the loop.

Using .keys() unnecessarily. for key in my_dict is equivalent to for key in my_dict.keys() — the longer form adds no value.

Assuming zip() handles unequal-length lists. It silently drops the extra items. Use itertools.zip_longest() if you need all items from both lists.