Learning to iterate through Python collections is what connects all four of the language's collection types: lists, tuples, sets, and dictionaries. Whether you are processing a list of measurements, walking through the keys of a dictionary, consuming items from a set, or stepping through nested grids of data, the for loop is the tool you reach for. Python's iteration protocol is uniform across collection types: anything you can put after the word in inside a for statement is an iterable, and every built-in collection is iterable. This uniformity means you learn one pattern and apply it everywhere.
The articles earlier in this section covered how to create, access, and modify each collection type individually. This article brings them together by focusing on the common operation of walking through every item. You will learn how iteration behaves differently across lists, tuples, sets, and dictionaries, how to get indices alongside values with enumerate, how to unpack nested structures directly in the loop header, and how nested loops handle multi-dimensional data. For the foundational understanding of how Python's for loop works, the article on Python for loops explained in the control flow section provides the underlying mechanics.
Iterating over sequences: lists and tuples
Lists and tuples are sequence types, which means iteration visits their items in order from the first element to the last. The for loop assigns each item to the loop variable in turn, and the loop body executes once per item. This is the simplest and most common iteration pattern in Python.
colors = ["red", "green", "blue"]
for color in colors:
print(color)For a tuple, the syntax is identical. The immutability of tuples does not affect iteration because reading items does not require modifying the collection. A for loop over a tuple produces the same ordered sequence of values as a for loop over an equivalent list.
When you need the position of each item alongside its value, wrap the iterable with the enumerate function. Enumerate produces pairs of index and value on each iteration, and unpacking those pairs in the loop header gives you both variables without manual index tracking. The index starts at zero by default, matching Python's zero-based indexing convention.
for i, color in enumerate(colors):
print(f"{i}: {color}")Enumerate is the idiomatic replacement for the pattern of maintaining a counter variable that increments inside the loop body. It is cleaner, less error-prone, and communicates the intent of indexed iteration directly.
Iterating over dictionaries
Iterating over a dictionary with a plain for loop yields its keys in insertion order. This is the simplest form of dictionary iteration and is appropriate when you only need the key names, such as when checking which configuration parameters are defined or which user IDs are present in a dataset.
For accessing values without the keys, use the values method. The values view iterates over every stored value in insertion order of their corresponding keys. This is useful for computing statistics like sums or averages over the values when the key identities do not matter.
The most common dictionary iteration pattern uses the items method with unpacking. Each iteration produces a key-value tuple, and unpacking the tuple directly in the for loop header assigns the key to one variable and the value to another. This pattern is the Pythonic way to process every entry in a dictionary and is the one you will see most often in production code.
scores = {"Alice": 92, "Bob": 85, "Charlie": 78}
for name, score in scores.items():
print(f"{name}: {score}")The items method returns a dynamic view, not a static list, so the loop reflects any changes made to the dictionary during iteration. However, modifying a dictionary's size while iterating over it raises a RuntimeError. If you need to filter entries during iteration, build a list of keys to delete and process them after the loop completes.
Iterating over sets
Sets iterate in an arbitrary order determined by their internal hash table. The same set may produce a different iteration order across different runs of the same program, or even within the same run if the set's internal structure changes. This unpredictability is a consequence of the hash-table implementation that gives sets their constant-time membership testing.
For most set use cases, the iteration order does not matter. When you use a set to collect unique items and then process each one, you typically do not care about the sequence. If you need a predictable order, pass the set to the sorted function, which returns a new list with the elements arranged from smallest to largest according to their natural comparison order.
unique_words = {"python", "set", "iterate", "loop"}
for word in sorted(unique_words):
print(word)The sorted function accepts any iterable and returns a sorted list. Using it with a set is a common pattern when you need both uniqueness, which the set provides, and ordering, which sorted provides. The article on Python collection membership testing covers how the in operator interacts with each collection type during iteration and search operations.
Iterating over nested collections
Nested for loops process multi-dimensional data by iterating over the outer collection and then iterating over each inner collection. The outer loop steps through rows, categories, or groups, and the inner loop steps through the items within each. This pattern works for nested lists, lists of tuples, dictionaries of lists, and any combination of nested collection types.
The order of nested loops follows the same leftmost-outermost convention as nested comprehensions. The outer loop variable changes least frequently, and the inner loop variable changes on every iteration. This is the same mental model as reading a grid row by row, left to right, top to bottom.
For deeply nested structures where the nesting depth is not known ahead of time, recursion replaces nested for loops. A recursive function that inspects each element and either processes it directly if it is a simple value or recurses into it if it is another collection can handle arbitrarily deep nesting. This pattern is more advanced but appears naturally when processing JSON data where the schema allows objects containing objects to arbitrary depth.
Rune AI
Key Insights
- A for loop iterates over any collection: lists and tuples yield items, dicts yield keys, sets yield arbitrary unique items.
- Use enumerate() to get both the index and the value while iterating over a sequence.
- Use dict.items() with unpacking to get both keys and values in a dictionary loop.
- Nested for loops iterate over nested collections row by row, element by element.
- Sets iterate in arbitrary order; use sorted() if you need a predictable sequence.
Frequently Asked Questions
How do I iterate over a dictionary and get both keys and values?
How do I get the index while iterating over a list?
Does iterating over a set preserve any order?
Conclusion
Iteration is the operation that unifies Python's four collection types. The same for loop syntax works across lists, tuples, sets, and dictionaries, and the patterns of unpacking, enumerate, and items cover the vast majority of everyday iteration needs.
More in this topic
Define and Call Python Functions
Learn the exact syntax for defining and calling Python functions with the def keyword, including naming rules, the function body, and how the call stack works.
Python Function Parameters and Arguments
Learn the difference between parameters and arguments, how to pass values by position and by keyword, and the rules for default parameter values.
Python Functions Explained
Learn what Python functions are, why they matter for organizing code, and how they form the foundation of non-trivial programs.