5 Essential Facts About For Loops in Python

For Loops in Python

For loops in Python are the standard way to repeat an action over every item in a sequence, from a list to a range of numbers.

A for loop repeats a block of code once for every item in a sequence – a list, a string, a range of numbers, or any other object Python can step through one item at a time. Where a while loop keeps running for as long as some condition stays true, a for loop simply asks: how many items are there, and what is each one? It runs its body exactly once per item and then stops on its own, with no separate condition to track or accidentally get wrong.

Basic Syntax

fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit)

Each time through the loop, the variable fruit is automatically set to the next item in fruits, in order, until the list runs out. No index variable, no manual counting – Python handles the bookkeeping.

Looping Over a Range of Numbers

When you want to repeat something a fixed number of times rather than loop over an existing collection, the built-in range() function generates a sequence of numbers to iterate over. It accepts up to three arguments – a starting point, a stopping point, and a step – though only the stopping point is required.

for i in range(5):
    print(i)          # 0, 1, 2, 3, 4

for i in range(2, 8):
    print(i)          # 2, 3, 4, 5, 6, 7

for i in range(0, 10, 2):
    print(i)          # 0, 2, 4, 6, 8

range(5) starts at 0 by default and stops one short of the number given, which is why it produces five numbers, not six. Adding a second argument sets an explicit start; adding a third sets the step size, and a negative step counts downward instead of up.

Tracking Position with enumerate()

Sometimes you need both an item and its position while looping – to number a list of results, for instance, or to know which index just matched something. Writing a separate counter variable and incrementing it by hand works, but Python provides a cleaner built-in for exactly this: enumerate().

fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
    print(index, fruit)

On each pass, enumerate() hands back a pair – the current index and the current item – which the loop unpacks directly into index and fruit. By default counting starts at 0, but enumerate(fruits, start=1) will count from 1 instead, which is handy whenever the numbering needs to match how people naturally count rather than how the computer indexes.

Looping Over Multiple Lists at Once with zip()

When you have two or more lists that line up item by item – names and ages, say – and want to loop over the pairs together, zip() combines them into a single sequence of tuples.

names = ['Ali', 'Sara', 'Bilal']
ages = [24, 31, 19]

for name, age in zip(names, ages):
    print(name, 'is', age, 'years old')

If the two lists are different lengths, zip() quietly stops at the end of the shorter one rather than raising an error, so it’s worth double-checking that both lists are the length you expect before relying on this pattern.

break, continue, and the Loop’s else Clause

Two keywords change a for loop’s normal path through a sequence: break exits the loop immediately, skipping any remaining items, and continue skips just the rest of the current pass and moves on to the next item.

numbers = [3, 7, 12, 9, 15]

for n in numbers:
    if n == 12:
        break
    print(n)

A less well-known feature, easy to miss if you’ve only used for loops in other languages, is that Python lets a for loop carry its own else clause. The code inside it runs once the loop finishes normally – but only if the loop was never interrupted by a break. This turns out to be exactly the right shape for a very common pattern: searching for something and needing to know whether it was actually found.

numbers = [3, 7, 9, 15]

for n in numbers:
    if n == 12:
        print('Found 12!')
        break
else:
    print('12 was not in the list')

Without the else clause, the same logic normally needs an extra flag variable set to False before the loop and checked again afterward, just to remember whether a match turned up. The for-else pattern folds that bookkeeping into the loop itself: the else block runs precisely when the loop reached its natural end without anyone calling break, and is skipped entirely the moment break does fire. The same else clause works on while loops too, with identical rules.

Nested for Loops

A for loop can contain another for loop inside it, which is useful whenever you need to pair every item from one sequence with every item from another – comparing all rows against all columns in a grid, for example.

for row in range(3):
    for col in range(3):
        print(f'({row}, {col})', end=' ')
    print()

For every single pass through the outer loop, the inner loop runs all the way through its own full sequence before control returns to the outer loop for its next item – so a 3-item outer loop wrapped around a 3-item inner loop runs the inner body nine times in total, not three. As with ordinary nesting in conditionals, keeping nested loops to a shallow depth is usually worth the effort; logic that needs three or four levels of nested loops is often a sign that the problem is better solved with a different data structure or a helper function.

To read more about repetition through loops in Python, see the while loop article, and for storing and working with the sequences these loops iterate over, see Lists in Python.

No Comments

Leave a Reply

Recent Comments

No comments to show.