How to use the Python for loop

The for loop construction in Python easily iterates over a collection of items. Here’s what you need to know to use it well.

How to use the Python for loop
tine ivanic

When you want to create a loop in Python, you generally have two choices: the while loop and the for loop. while is simple: it just repeats until a given condition is no longer true. The for loop is more complex, and thus more powerful: for lets you iterate through objects in a collection of some kind without having to know details about the collection.

Python for loop components

A Python for loop has two components:

  • A container, sequence, or generator that contains or yields the elements to be looped over. In general, any object that supports Python’s iterator protocol can be used in a for loop.
  • A variable that holds each element from the container/sequence/generator.

In the following example, we loop through a list of numbers, and use the variable digit to hold each number in turn:

for digit in [3,1,4,1,5,9]:
    print (digit)

This will print:

3
1
4
1
5
9

If you are iterating through an object that yields containers or sequences, you can use Python's multi-assignment syntax to unpack them. For instance:

for letter, number in [["a",1],["b",2]]:
    print (letter, number)

The output:

a 1
b 2

Common Python for loops

Here are some common objects used in a Python for loop:

Lists

The example above shows how a list can be iterated over using a for loop. Note that if you have a list of lists, each element extracted by the for loop will itself be a list. for loops do not automatically “flatten” nested structures of any kind.

Strings

Strings in Python are considered “sequences” — they can be iterated over, and the results of iterating over a string are each character in the string.

for letter in "Hello world":
    print (letter)

This would yield:

H
e
l
l
o

w
o
r
l
d

Dictionaries

Iterating through a dictionary with a for loop yields each key in the dictionary.

d1 = {
    "a": 1,
    "b": 2
}

for key in d1:
    print (key)

This would yield:

a
b

If you want to iterate through the values of a dictionary, use the dictionary’s .values() method. You can also iterate through keys and values together, with .items():

d1 = {
    "a": 1,
    "b": 2
}

for key, value in d1.items():
    print (key, value)

This would yield:

a 1
b 2

Generators

Generators yield a succession of items, one for each time they’re called. A common example of a generator used in a for loop is range.

for n in range(50):
    print (n)

This would print the numbers 0 through 49.

Note that just because you can use a generator in a for loop doesn’t mean that the generator will eventually stop of its own accord. For instance, this for loop will run forever:

def forever():
    while True:
        yield 1

for n in forever():
    print (n)

In such cases you may want to take steps to ensure the loop can terminate. (See “Flow control” below.)

Using indexes and enumerate with a Python for loop

Developers who come to Python from languages like C, C++, or Java will often create an index variable that is used to step through the object being iterated. An example:

x=[3,1,4,1,5,9]
n = 0
while n<len(x):
    print (x[n])
    n+=1

This isn’t wrong as such, but it misses the point of how Python works. A for loop in Python doesn’t require an index; it can just traverse the object to be iterated over without needing to index into it.

However, sometimes you need to keep track of which element you’re dealing with while looping. Python’s enumerate() utility helps with this. It takes an iterable and upon each iteration generates a tuple of the index and the object at that index:

x = [3,1,4,1,5,9]
for index, n in enumerate(x):
    print (index, n)
0 3
1 1
2 4 
3 1
4 5
5 9

Flow control in a Python for loop

for loops don’t always run to completion, or in exact sequence. Sometimes you want to leave a for loop early, or skip over an item in the loop. To do that, Python provides you with two keywords: break and continue.

for n in range(20):
    if n % 2 == 0: # if n is a multiple of 2
        continue   # then skip it
    # everything after this point is not run
    # if `continue` is invoked
    print (n)
print ("Done")

This yields 1 3 5 7 9 11 13 15 17 19, then Done. Note that when the loop ends, the program continues normally at print ("Done").

for n in range(20):
    if n == 10:
        break # leave the loop altogether
    print (n)
print ("Done")

This prints the numbers 0 through 9, then Done.

Note that if you have loops nested inside other loops, break will only affect the current loop — it won't exit from all loop levels. Exiting from multiple for loops requires a different mechanism, like a sentinel variable:

done = False
for n in range(20):
    for m in range(40):
        if n==10 and m==10:
            done = True
        if done: break
    if done: break

A Python for loop gotcha

When iterating over the elements of an object in a for loop, don’t do anything that would alter the members or length of the sequence. For instance, if you’re iterating over a list, don’t add or remove elements from the list as you iterate.

If the reason you’re iterating over elements is to test each element to see if you need to add or remove something, there is a better solution. Create a new, empty container, populate it only with the elements you want to keep, then replace the old container with the new one.

Here is an example with a list. This creates a new list that contains only odd numbers:

old_list = [1,2,3,4,5,6]
new_list = []
for n in old_list:
    if n % 2:
        new_list.append(n)
old_list = new_list

Copyright © 2021 IDG Communications, Inc.

InfoWorld Technology of the Year Awards 2023. Now open for entries!