For loops

Martin McBride, 2018-03-02
Tags for loop list iterator generator list comprehension
Categories python language intermediate python

You will probably have met for loops in conjunction with the range function, in simple code like this:

for i in range(5):

This code prints values 0, 1, 2, 3, and 4. It is more or less the Python equivalent of the following C or Java style loop:

for (i = 0; i < 5; i++)

In fact, in Python, loop indices (the variable i) not used all that often - it might even be considered un-Pythonic. Usually for loops are used to loop directly over a list or other sequence of values.

In this tutorial we will look at various other techniques available in Python to make your loops shorter and easier to read. More techniques are discussed in the articles on reverse and sort, zip and enumerate and filter.

Looping over a list

Suppose you wanted to loop over all the values in a list. New Python programmers will often write something like this:

k = ['red', 'green', 'blue']
for i in range(3):

This works perfectly well, of course, but Python provides a better way. You can loop over a list directly, without using an index variable:

k = ['red', 'green', 'blue']
for s in k:

Here is how the for loop works:

Loop over each element is k, and for each element:
    assign the element to variable s
    execute the body of the loop

Why this is better

Looking at the two loops, clearly the second loop has no need for the extra variable i. While that is obviously a good thing, simpler code is always better, that isn't the main benefit. Look at the for loop line:

for s in k:

This tells you exactly what the code is doing - it is looping over the list k. Compare this with the first case:

for i in range(3):

All this tells you is that the loop will run 3 times. You have to look at the code inside the loop to figure out that each pass through the loop is actually processing the next element of k. That isn't too hard to do in this case because the loop body only contains one line, but in a more complex loop you might have to study the code to work out what the loop is actually doing.

Looping over iterables

A for loop can loop over any iterable item. This includes sequences such as lists, tuples or strings. Looping over a tuple is exactly the same as looping over a list, but looping over a string is slightly different (but very useful):

s = 'hello'
for c in s:

In this case, on each pass of the loop, c contains the next character of the string. So the first time through the loop will print 'h', the next time will print 'e', and so on.

Python doesn't have a special data type for a character. A character is represented by a string of length 1.

for can also be used with other types of iterables such as generators and list comprehensions. These objects don't work in quite the same was as a list. A list has all its values available before the loop starts - they are just the values in the list. A generator, alternatively, doesn't create values until it is asked for them. This is called lazy iteration

How does range work?

So, to go right back to the beginning, how does range work? range is a function, so you might simplistically think of it as a function that returns a list:

v = range(5)   # v = [0, 1, 2, 3, 4] ? No!

In fact, this is how range used to work in Python 2. But since Python 3, the range function returns a range object, that is a lazy iterable. It creates the sequence of values 0 to 4, one at a time, when the for loop requests them.

In summary, where possible, avoid using a loop counter variable, and loop over the sequence directly. This simplifies the code and makes the intent clear.

If you found this article useful, you might be interested in the book Python Quick Start or other books by the same author.


Popular tags

2d arrays abstract data type alignment and angle animation arc array arrays bar chart bar style behavioural pattern bezier curve built-in function callable object chain circle classes clipping close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data science data types decorator design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif global variable gradient greyscale higher order function hsl html image image processing imagesurface immutable object in operator index inner function input installing iter iterable iterator itertools join l system lambda function len lerp line line plot line style linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map marker style matplotlib monad mutability named parameter numeric python numpy object open operator optimisation optional parameter or pandas partial application path pattern permutations pie chart polygon positional parameter print pure function python standard library radial gradient range recipes rectangle recursion reduce regular polygon repeat rgb rotation roundrect scaling scatter plot scipy sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency triangle truthy value tuple turtle unpacking user space vectorisation webserver website while loop zip