These questions ask you to predict what a loop consumes, binds, skips and leaves behind. Trace the iterable or condition first, then follow the control path one pass at a time.
Trace a loop in three passes
First identify the source. A for loop requests successive items from any iterable and assigns each item to its target; it does not need a numeric position. For example, for letter in "sun": print(letter) visits three string items. A while loop instead checks a truth condition before every attempted pass, so while ready: work() may run zero times when ready begins falsy.
Second trace any producer or target shape. A range produces integers and excludes its stop value. With range(stop), the omitted start is zero and the omitted step is one; range(2, 8, 2) instead starts at two, advances by two and stops before eight. enumerate("go") produces counter-item pairs beginning with counter zero unless another start is supplied. zip("ab", "xyz") stops as soon as the shorter input is exhausted. A target such as for name, score in pairs: show(score) requires every visited item to provide exactly two values.
Third follow exits and results. break leaves only the nearest loop; continue skips the rest of the current pass and advances that loop. An attached else runs after normal exhaustion, even after zero passes, but not after break. Direct dictionary iteration visits entries by their names in insertion order. After a nonempty for loop, the target remains bound to its final item. In [n + 1 for n in nums if n is greater than 0], the filter admits items, the expression transforms them, and a new list receives the results.
Reject these tempting routes
| Tempting route | How to reject it |
|---|---|
| Treat every for loop as a counter over a copied list | Read the expression after in as an iterable. Its successive items are bound directly, whether they are numbers, characters or other objects. |
| Assume a while body runs once before its condition matters | Place the condition check before the body on your trace. An initially falsy condition means no first pass. |
| Let break end every surrounding loop, or let continue restart the same pass | Both statements act on the nearest loop. Break leaves it; continue abandons only the remaining work of this pass and advances. |
| Start enumerate at one or expect zip to pad unequal inputs | Use the documented defaults: enumerate begins at zero, and ordinary zip finishes with the shortest iterable. |
| Expect direct dictionary iteration to yield values in sorted order | It yields entry names in insertion order. Request a values view or an items view when the loop needs a different shape. |
| Treat a list comprehension as an in-place edit or a generator | Run its filter and expression for each input, then place the produced values in a new list. |
Try it
Classify the range rules for range(stop) and range(start, stop, step). Which statements are true? Select all that apply.
- An omitted start is zero.
- The stop value is excluded.
- An omitted step is one.
- The produced values are floats.
- The stop value is always included.
Spot the loop-else misconception: a for loop receives an empty iterable, performs zero passes, and encounters no break. What happens to its attached else suite?
- It is skipped because the body never ran.
- It runs because no break occurred.
- It raises an error because the loop was empty.
- It runs only when a break occurs.
In for key, value in items, what must be true of every visited item for the two-name loop target to unpack successfully?
- Every item may have any number of values.
- Every item must supply exactly two values.
- Items must alternate between key and value.
- Only dictionary keys may be visited.