Python Programming · Foundations
For Loops
On this page 9 sections
In 30 seconds
A Python for loop takes items from an iterable An object that can supply items for iteration, such as a string, a list, or a range object. Full entry → one at a time and runs an indented block for each item. The loop target The assignment target in a for statement that receives the current item or unpacked part of an item. Full entry → is the name that receives the current item. Use for color in colors when the values matter, range() when a numeric sequence is appropriate, and enumerate() when you need both a position and a value.
Why this matters
For loops let a program apply the same small operation to every item in a sequence without copying the operation by hand. They are central to introductory programming exercises, data cleaning, text processing, and later algorithms. Learning the difference between an item and its position also helps students write clearer code: direct iteration The process of taking successive items from an iterable and performing a loop's suite for each one. Full entry → expresses work on values, while enumerate() expresses work that needs a numbered location.
The college version
Iteration and the shape of a for statement
A for statement expresses iteration: repeated work over the successive items supplied by an iterable. An iterable is an object that can provide items for iteration; common beginner examples are strings, lists, and range objects. In for item in iterable:, Python obtains one item, assigns it to item, and executes the indented suite The indented block of statements controlled by a Python statement such as for. Full entry →. It repeats that process until the iterable has no more items. The loop does not mean “repeat a fixed number of times” in every case. It means “visit the items this iterable supplies.” That distinction makes direct iteration easy to read: for name in names: says that the body works with each name, not with a mysterious counter.
The target can be any valid assignment target, commonly a simple name. Its value changes as the loop advances. The colon and indentation are structural, not decoration: the indented statements form the suite that runs once per supplied item. A line at the outer indentation is outside the loop and runs after iteration finishes. Keep the loop body focused on the current item, and choose a target name that explains what that item represents. This lesson concentrates on ordinary for iteration; conditionals, while loops, and custom iterator machinery are separate topics.
Using range without an off-by-one error
range() is useful when the loop should receive a progression of integers. With one argument, range(stop) begins at 0 and stops before stop. Thus range(4) supplies 0, 1, 2, and 3: four values, not five. With three arguments, range(start, stop, step) supplies values separated by step while still excluding stop. For example, range(2, 10, 3) supplies 2, 5, and 8. A negative step can move downward when its start, stop, and step agree.
The excluded endpoint is a frequent source of off-by-one mistakes, so trace a small range A built-in object for an arithmetic progression of integers, commonly used in numeric iteration. Full entry → rather than guessing. Python's tutorial describes range() as generating arithmetic progressions and explains that a range object supplies values as it is iterated; it is not itself a list of all those values. Use range() when the number sequence is the thing the program needs—for example, a fixed set of numbered attempts. Do not reach for range(len(items)) merely to obtain each value of a sequence. Direct iteration is usually clearer when only the values are needed. For instance, for title in titles: tells the reader immediately that the body uses titles. An index is useful only if its number has a purpose, such as referring to a particular location or displaying an ordered label. Choosing the direct form when possible reduces the chance of accidentally using a number where the program expected the item.
Positions and values with enumerate
Sometimes a loop needs both an item and a count showing its position. enumerate(iterable) produces pairs containing a count and each value from the iterable. Its count defaults to 0, and enumerate(iterable, start=1) changes the first count to 1. Python can unpack each pair into two loop targets: for position, color in enumerate(colors, start=1):. On the first pass, position receives 1 and color receives the first color; on the next pass they receive the next pair.
This pattern communicates intent better than manually maintaining a counter, and it avoids mixing up an index with an item. It is especially useful for user-facing numbered lists, where numbering often begins at 1 even though many Python sequence positions begin at 0. enumerate() does not change the underlying iterable; it yields count-and-value pairs while the loop runs. If the program only needs each color, for color in colors: remains the simplest expression. If it needs a number displayed next to each color, use enumerate() and state the starting number explicitly. A loop header should make clear whether the body needs the value, its displayed position, or both; that choice is part of communicating the program's purpose to a future reader.

Eli explains
The same idea, in plain words
Explain it like I’m 10
Imagine a row of labeled bins. A for loop opens one bin at a time, gives its contents a temporary name, and performs the same instruction on those contents. When the row ends, the repeated job ends. The name after for is not a container holding all the bins; it is the label for the item currently being handled.
range() is like a ticket dispenser whose last printed number is just before the number on its stop sign. range(4) hands out 0 through 3. enumerate() is like putting a number sticker on each bin as you visit it. It gives you both the sticker number and the bin's contents, so you can say “1: red” and then “2: blue.”
Picture it like this
A for loop is a cafeteria line: the server handles one tray at a time using the same procedure. enumerate() adds a tray number to each handoff.
Where the picture stops working
A real cafeteria line may change its procedure or add trays while it operates. The basic examples here assume the iterable supplies items in order and focus only on the loop's ordinary visit-one-item-at-a-time behavior.
Worked example
Suppose a program needs to print a numbered packing list. colors = ['red', 'blue'] is the iterable. The loop for position, color in enumerate(colors, start=1): receives the pair (1, 'red') first, so print(position, color) prints 1 red. The next pair is (2, 'blue'), printing 2 blue. The output is therefore:
1 red
2 blueFor a numeric progression, for n in range(2, 10, 3): print(n) visits 2, 5, and 8. It does not visit 10 because range excludes its stop endpoint.
Key takeaway
A Python for loop visits the items an iterable supplies and runs its indented suite once per item. Use direct iteration for values, range() for a numeric progression with an excluded stop, and enumerate() when a count and value belong together.
Quick check
3 questions here, of 5 in this lesson’s practice set. Answers stay hidden until you check.
In
What values are printed by for n in range(2, 10, 3): print(n)?
Which loop is clearest when a program only needs to print every name in names?
Study tools & related lessonsYou’ll learn to · Common mistakes · Easily confused · Key vocabulary · Related
You’ll learn to
- Define an iterable, loop target, and loop suite.
- Explain how a
forstatement assigns successive items to its target. - Apply
range()while accounting for its excluded stop endpoint. - Use
enumerate()to obtain a position and value together. - Trace the output of a short
forloop.
Common mistakes
Expecting
range(4)to include 4.Trace it as 0, 1, 2, 3; the stop endpoint is excluded.
Using
range(len(items))when the loop only needs each item.Write
for item in items:for direct, value-focused iteration.Treating the loop target as a collection of all items.
It names the current item for the current pass through the suite.
Manually changing a counter when a count and value are needed together.
Use
enumerate(iterable, start=...)and unpack its pair into two targets.
Easily confused
`for item in items` vs. `for index, item in enumerate(items)`
The first supplies values only; the second supplies a count and a value.
`range(4)` vs. `[0, 1, 2, 3]`
Both can supply these values in iteration, but range is a range object rather than a list.
Key vocabulary
- iteration
- The process of taking successive items from an iterable and performing a loop's suite for each one.
- iterable
- An object that can supply items for iteration, such as a string, a list, or a range object.
- loop target
- The assignment target in a for statement that receives the current item or unpacked part of an item.
- suite
- The indented block of statements controlled by a Python statement such as for.
- range
- A built-in object for an arithmetic progression of integers, commonly used in numeric iteration.
- stop endpoint
- The boundary passed to range that the generated progression does not include.
- enumerate
- A built-in function that yields a count together with each value from an iterable.
Sources & references
- 8. Compound statements - The Python Language Reference (while, for, break, continue) — Python Software Foundation
- The Python Tutorial — 4. More Control Flow Tools (if Statements) — Python Software Foundation
- Built-in Functions — Python 3 documentation — Python Software Foundation
EliExplains lessons are original prose written from the open, credible references above. See Copyright & Licensing.
Researched 2026-08-19
Educational content only. It is not medical, legal or professional advice. Found an error? Tell us.

