Nested Loops and Patterns
A middle-school coding lesson on nested loops: learn how a loop inside a loop works, why the inner loop runs fully for each outer step, and use them to build grids, tables and patterns in Scratch and Python. With quiz.
Key takeaways
- A nested loop is a loop placed inside another loop
- For every single pass of the outer loop, the inner loop runs all the way through
- If the outer loop runs M times and the inner runs N times, the body runs M × N times
- Nested loops are perfect for grids, tables, and any pattern with rows and columns
From one loop to a loop inside a loop
You already know a loop repeats a set of instructions. If you need a refresher, read loops and repeats first, because this lesson builds directly on it.
A single loop is great for repeating a line of stars:
for col in range(5):
print('*', end='')
print()
This prints one row: *****. The end='' tells Python not to jump to a new line after each star, so they sit side by side. The final print() ends the row.
But what if you want five rows of five stars — a whole square? You could copy the loop five times, but that is exactly the kind of repetition loops are meant to remove. Instead, you wrap one loop inside another. A loop inside a loop is called a nested loop.
How a nested loop runs
This is the single most important idea in the whole lesson, so read it carefully:
For every single pass of the outer loop, the inner loop runs all the way through.
Think of it like a clock. The minute hand (the inner loop) sweeps all the way around 60 times for each single step of the hour hand (the outer loop). The inner thing completes a full cycle before the outer thing moves one step.
Here is a tiny example you can trace by hand:
for outer in range(2):
print("Outer", outer, "starting")
for inner in range(3):
print(" inner", inner)
Let's walk through it exactly the way the computer does:
Outer 0 starting
inner 0
inner 1
inner 2
Outer 1 starting
inner 0
inner 1
inner 2
Notice how the inner loop counts 0, 1, 2 completely before the outer loop moves from 0 to 1. The inner loop "resets" and runs fully again on the next outer pass.
Counting the total runs
There is a simple rule for how many times the inner body runs in total:
If the outer loop runs M times and the inner loop runs N times, the inner body runs M × N times.
In the example above, the outer loop ran 2 times and the inner loop ran 3 times, so the inner body ran 2 × 3 = 6 times. Count the inner lines in the output — there are exactly six.
This multiplication is powerful, but it is also a warning. If you nest a loop that runs 1,000 times inside another that runs 1,000 times, the body runs one million times. Nested loops can do a lot of work, so always think about how big M and N are.
Building a grid of stars
Now back to our square. We want 5 rows, each with 5 stars. The outer loop handles the rows, and the inner loop handles the columns:
for row in range(5):
for col in range(5):
print('*', end='')
print()
Read it like this:
- The outer loop picks a row. For each row, it does everything inside.
- The inner loop prints 5 stars side by side using
end=''. - After the inner loop finishes, the lone
print()ends the line, dropping to the next row.
The output is a neat 5×5 square:
*****
*****
*****
*****
*****
The big idea: outer loop = rows, inner loop = columns. This pattern shows up everywhere, from drawing tile maps to filling spreadsheets.
Making real patterns
Once you have the grid working, small changes create surprising patterns. Suppose we print a number of stars equal to the row number:
for row in range(1, 6):
for col in range(row):
print('*', end='')
print()
Here the inner loop runs row times — it depends on the outer loop's value! Row 1 prints 1 star, row 2 prints 2 stars, and so on. The result is a triangle:
*
**
***
****
*****
This is a key trick: the inner loop's count does not have to be a fixed number. It can use the outer loop's variable to make growing or shrinking patterns.
Nested loops in Scratch
You do not need typed code to use nested loops. In Scratch, you simply drop one repeat block inside another. Here is a script that draws a row of 5 squares using the Pen blocks:
when green flag clicked
go to x: -200 y: 0
pen down
repeat 5
repeat 4
move 40 steps
turn 90 degrees
move 50 steps
The inner repeat 4 draws one square (four sides, turning 90 degrees each time). The outer repeat 5 draws that square five times, moving over by 50 steps between each one. One loop inside another — same idea, visual blocks. If C-blocks are new to you, see introduction to block coding and getting started with Scratch.
A practical example: the times table
Nested loops shine when you have rows and columns of data. A multiplication table is a perfect example:
for a in range(1, 4):
for b in range(1, 4):
print(a * b, end='\t')
print()
The outer loop picks the first number a; the inner loop multiplies it by every b. The \t is a tab, which lines the numbers up in columns. The output is:
1 2 3
2 4 6
3 6 9
You wrote a whole multiplication grid with just four lines. Imagine doing that by hand for a 12×12 table — the nested loop does the boring work for you.
A common bug: where does the line break go?
The most frequent nested-loop mistake is putting the print() (the line break) in the wrong place. Compare these two:
# Correct: line break AFTER the inner loop
for row in range(3):
for col in range(3):
print('*', end='')
print()
# Bug: line break INSIDE the inner loop
for row in range(3):
for col in range(3):
print('*', end='')
print()
The first prints a tidy 3×3 square. The second prints a single column of nine stars, because it starts a new line after every star. The fix is all about indentation — which loop a line belongs to. When a nested loop misbehaves, check exactly which loop each line is inside.
Try it: draw a checkerboard
Here is your challenge. Write a Python program that prints an 8×8 checkerboard using # for dark squares and a space for light squares, like this (first few rows):
# # # #
# # # #
# # # #
# # # #
Hints to guide you:
- Use an outer loop for the 8 rows and an inner loop for the 8 columns.
- Inside the inner loop, decide which character to print. A square is dark when
(row + col)is even. You can check that withif (row + col) % 2 == 0:. - Print
#for dark and a space for light, usingend=''so they stay on one line. - Remember the
print()after the inner loop to end each row.
When your checkerboard appears, change the size to 4×4 or 10×10 and watch it scale instantly. That is the power of nested loops: write the logic once, and it handles any size grid. Once you are comfortable here, the same row-and-column thinking will help you work with lists and arrays and 2D data. 🔳
Quick quiz
Test yourself and earn XP
What is a nested loop?
A nested loop is one loop written inside another loop. The inner one is 'nested' in the outer one.
If the outer loop runs 3 times and the inner loop runs 4 times, how many times does the inner body run in total?
For each of the 3 outer passes, the inner loop runs 4 times, so 3 × 4 = 12 times in total.
When does the inner loop run?
The inner loop runs all the way through during each pass of the outer loop.
What will this print? ``` for row in range(2): for col in range(3): print('*', end='') print() ```
The outer loop makes 2 rows; the inner loop prints 3 stars per row, then print() ends each row.
Which task is a NATURAL fit for nested loops?
Anything with rows and columns, like a grid or table, maps cleanly onto an outer loop and an inner loop.
FAQ
Yes. You can put a loop inside a loop inside a loop, and so on. Three levels is common for 3D grids, but each extra level multiplies the work, so they can get slow quickly.
The outer loop usually controls the rows and the inner loop controls the columns. Swapping them changes how the pattern is built and read, even if the total count stays the same.
Keep exploring
More in Coding