In Python as in other languages, a lot of the work done by a program tends to be quite boring. Scripts and applications have to repeat the same process, such as calling a function or replacing a string, sometimes millions of times. The good news is that every language has features to condense these actions into a few lines of code. In this article, we’re going to talk about a particularly handy feature: the for loop.

What Is a For Loop?

A for loop (also: for-loop, for loop) is a computer science concept allowing us to iterate over some sequence. It may be combined with other statements such as if-else or try-except statements, or even other for loops. What makes the for loop so useful is that it repeats the same operation for each element in a sequence, saving us on the space and time it would otherwise take to redefine a given operation over and over again. 

In the C language, a for loop iterates over a sequence of numbers. While we can easily use a for loop to accomplish the same in Python, the way a Python for loop is defined facilitates its ability to deal with other sequences, such as lists or strings. The for loop in Python is called a for-each loop in some other languages.

For Loops in Python

Looping Over Integers

If we were to traditionally iterate over a sequence of numbers in a Python for loop, we’d combine it with a range() function. range() takes three arguments: the start point, endpoint, and step size. For instance, range(0, 3, 1) would generate the sequence [0,1,2], since the start point is inclusive, but the endpoint is not. 

The default start point is zero and the default step size is one. If we want to loop over a sequence of numbers, by convention we often use the variable i (short for integer).

>>> for i in range(3):
…     print(i)
>>> for i in range(3, 10, 3):
…     print(i)

Quick check: Do you understand how range() behaves in these two loops?

Looping Over Other Data Types

While range() is a handy shortcut, we could get the same behavior by spelling out the list of integers. For example:

>>> for i in [0, 1, 2]:
…     print(i)

The list in Python is a welcoming data type; it can contain all kinds of variables: integers, strings, Booleans, or even other lists. Let’s look at how to write a for loop for a list of strings:

>>> for name in [‘maya angelou’, ‘nikki giovanni’]:
…     print(name)
maya angelou
nikki giovanni

And how about a list with mixed data types? 

>>> for item in [‘maya’, 3, True]:
…     print(item)


We can even loop over a string, since it is a sequence of letters.

>>> for letter in ‘maya’:
…     print(letter.upper())


Nested For Loops

Here’s where things get interesting. You can put a for loop within another for loop to create a nested loop. Let’s write a little program for finding all the prime numbers among the first 10 natural numbers. 

Remember that a prime number is a number that can only be divided by itself and one. We start our sequence at two because one is not a prime number (it only has one positive divisor, not two). The internal loop only takes a range up to five, because in our scenario, the divisor can’t be larger than half the dividend.

>>> for i in range(2, 10):
…     prime = True
…     for j in range(2, 5):
…         if i%j == 0 and i != j:
…             prime = False
…     if prime:
…         print(‘{} is prime’.format(i))

2 is prime
3 is prime
5 is prime
7 is prime

Nested for loops are quite useful for creating a grid-like data structure (such as a table). You could even work with multi-dimensional grids (aka matrices), adding more for loops into your for loops (more on that below).

Modifying the Behavior of a For Loop

As we’ve seen, a normal for loop will terminate after looping over every item in a given sequence. We could change that behavior by using the statements break, continue or pass. These are used in combination with if-else statements, which are conditional statements that check if a condition is True, and run a command if it is. Let’s first write a basic for loop:

>>> for fruit in [‘melon’, ‘kiwi’, ‘blueberry’, ‘mulberry’, ‘pitaya’]:
…     if fruit[-5:] == ‘berry’:
…         print(‘A {} is a berry.’.format(fruit)) 

A blueberry is a berry.
A mulberry is a berry.

In this example, we made use of our ability to access the individual letters of the string by their indices to check whether the last five letters of a word spell “berry.”

Now let’s say we don’t want any berries at all in our fruit basket. Perhaps we’re allergic or simply prefer tropical fruits. We could tell our for loop to stop working upon encountering any kind of berry.

>>> for fruit in [‘melon’, ‘kiwi’, ‘blueberry’, ‘mulberry’, ‘pitaya’]:

…     if fruit[-5:] == ‘berry’:
…         break
…     print(fruit)


As we can see, the break statement caused the program to stop. That’s why the program’s output only contains the first two fruits. If we wanted to get the pitaya as well, we could have used continue instead of break. The continue statement tells the program to do nothing and simply move on to the loop’s next iteration.

>>> for fruit in [‘melon’, ‘kiwi’, ‘blueberry’, ‘mulberry’, ‘pitaya’]:
…     if fruit[-5:] == ‘berry’:
…         continue
…     print(fruit)


A subtly different statement is pass. Like continue, it allows the loop to continue, but it’ll simply ignore the fact that the condition evaluates to True.

>>> for fruit in [‘melon’, ‘kiwi’, ‘blueberry’, ‘mulberry’, ‘pitaya’]:
…     if fruit[-5:] == ‘berry’:
…         pass
…     print(fruit)


When Not to Use For Loops

By now, you’re probably convinced of the Python for loop’s utility. If used correctly, this Python feature can save you time and space, and make for elegant, readable code. However, there are also plenty of scenarios in which the use for loops is not advised. We’ll be consulting the Zen of Python to see why we shouldn’t use for loops in at least two situations.

When There Are Simpler Ways

Line three of the Zen of Python states that “simple is better than complex.” Well, the language happens to offer features that simplify for loops, most notably list comprehensions, which are one-liners that can squeeze a simple for loop into one list. In a slight modification of a common example, let’s square our four one-digit prime numbers. Here’s how we’d do it in a loop:

>>> for prime in [2, 3, 5, 7]:
…     print(prime**2)


And with a list comprehension: 

>>> [prime**2 for prime in [2, 3, 5, 7]]

[4, 9, 25, 49]

Granted, the output is slightly different. But in most cases, a list comprehension will work better than your simple for loop. You could even do nested comprehension and add if-else statements, but remember to keep it simple, which brings us to our next case.

When They Impact Readability 

Writing a multiple nested loop might look cool and economic, but if you get to a point where you don’t remember what the outermost loop was doing, you should rethink the design of your code. As line eight of the Zen of Python states, “readability counts,” and this should be your guiding principle when writing code meant to be read by others — or by yourself for that matter.

While Python can theoretically handle up to 20 levels of nesting, you probably shouldn’t use more than four. If you get to that number, think about modifying your code to make it more modular, to thereby increase its readability.

Learn More

We hope you enjoyed reading about for loops in Python. To master key programming concepts and hone your coding skills, check out our Intro to Programming Nanodegree.

Start Learning