# Nested loops

You are allowed to put one loop inside another. Here is an example.

```for m in range(1, 5):     line = ''     for n in range(1, 5):         line = line + ' ' + str(m * n)     print(line) ```

Having one loop inside another is called a nested loop. Since it's useful to have names for loop for discussion purposes, we call the two loops the outer loop (“`for m`…” in our example) and the inner loop (“`for n`…”).

There's nothing special about nested loops as far as Python is concerned. Just as before, it iterates through the outer loop; and for each iteration, it goes through the statements of the body. It happens that one of those body's statements is the inner loop, which it executes in full before proceeding to the next line.

The net effect is that when `m` is 1, this program will iterate through the inner loop with `n` taking on each value between 1 and 4. Then when `m` is 2, this program iterates again through the inner loop with `n` taking on each value between 1 and 4. And it does the same when `m` is 3 and when `m` is 4. Here is a complete trace of what happens to the variables as the program executes.

 `m` `n` `line` display 1 “” 1 “`1`” 2 “`1 2`” 3 “`1 2 3`” 4 “`1 2 3 4`” `1 2 3 4` 2 “” 1 “`2`” 2 “`2 4`” 3 “`2 4 6`” 4 “`2 4 6 8`” `2 4 6 8` 3 “” 1 “`3`” 2 “`3 6`” 3 “`3 6 9`” 4 “`3 6 9 12`” `3 6 9 12` 4 “” 1 “`4`” 2 “`4 8`” 3 “`4 8 12`” 4 “`4 8 12 16`” `4 8 12 16`

The overall result is that this program displays a multiplication table up to 4 × 4.

`1 2 3 42 4 6 83 6 9 124 8 12 16`

This output has some redundancy: The northeast half is the same as the southwest half, just reflected. For example, it includes both 1 × 4 and 4 × 1. Suppose we want to display only the lower left triangle.

`12 43 6 94 8 12 16`

To do this, we just change the second argument to `range` in the inner loop, so it counts only as far as `m` before stopping.

```for m in range(1, 5):     line = ''     for n in range(1, m + 1):         line = line + ' ' + str(m * n)     print(line) ```