PYTHON

Python Nested Loops: Syntax, Usage, and Examples

Nested loops in Python are loops placed inside other loops, so the inner loop runs fully for every single step of the outer loop. You use them when you need to work through “two layers” of data, like rows and columns, or people and their tasks.


How to Use Nested Loops

A nested loop is simply a loop inside another loop. Python lets you combine any loop types, but the most common pattern is one for loop inside another for loop.

Basic syntax

for outer_itemin outer_iterable:
for inner_itemin inner_iterable:
# Code that uses outer_item and inner_item

Here’s what happens:

  • The outer loop picks one value.
  • The inner loop runs completely for that value.
  • The outer loop moves to the next value, and the inner loop runs again.

You can also nest while loops, or mix for and while:

row =0
while row <3:
for colinrange(3):
print(row, col)
    row +=1


When to Use Nested Loops

Nested loops can look scary at first, but they’re very practical. You’ll run into them often when working with structured data or multi-step processes.

1) Working with rows and columns (grids)

Any time you deal with a 2D layout, nested loops are the go-to tool.

Examples:

  • Sudoku or chess boards
  • Pixel-based images
  • Seat maps in a theater
  • Spreadsheet-like data

Outer loop usually handles rows, inner loop handles columns.

2) Looping through lists inside a list

Python often stores grouped data as a list of lists, also called a nested list.

Example:

  • A class list where each student has a list of grades
  • A weekly plan with tasks per day
  • A menu with categories and items

Nested loops let you process every inner item without writing repetitive code.

3) Building combinations or comparing two collections

Sometimes you need to compare every item from one list to every item in another list.

For example:

  • Matching users to available time slots
  • Checking if products appear in two different inventories
  • Finding shared tags between two posts

This works, but keep an eye on performance. Comparing “everything with everything” can get expensive with large lists.

4) Creating patterns or formatted output

If you’ve ever printed a triangle of stars, a multiplication table, or a simple ASCII art grid, you’ve probably used nested loops.

They’re useful for generating repeated output that has structure, not just repetition.


Examples of Nested Loops

Let’s make nested loops feel more natural by using real code you might write in everyday projects.

Example 1: Looping through a 2D grid

A simple board can be represented as a list of rows, where each row is a list of cells.

board = [
    ["⬜","⬜","⬜"],
    ["⬜","⬛","⬜"],
    ["⬜","⬜","⬜"]
]

for rowin board:
for cellin row:
print(cell, end=" ")
print()

Output:

⬜ ⬜ ⬜
⬜ ⬛ ⬜
⬜ ⬜ ⬜

The outer loop goes through each row, and the inner loop prints each cell.


Example 2: Totaling grades for each student

Here’s a list where each student has multiple quiz results.

students_scores = [
    [8,10,7],
    [9,9,10],
    [6,7,8]
]

for i, scoresinenumerate(students_scores):
    total =0
for scorein scores:
        total += score
print(f"Student {i + 1} total:{total}")

Output:

Student 1 total:25
Student 2 total:28
Student 3 total:21

Each student’s score list gets processed separately, but the pattern stays the same.


Example 3: Find duplicate items across categories

Imagine you have product categories and want to spot repeated products.

categories = {
"Snacks": ["chips","nuts","cookies"],
"Drinks": ["water","juice","nuts"],
"Fruit": ["banana","apple","juice"]
}

seen =set()

for category, itemsin categories.items():
for itemin items:
if itemin seen:
print(f"Duplicate item found: {item}")
        seen.add(item)

Output:

Duplicate item found:nuts
Duplicate item found:juice

This is a common “scan everything inside everything” situation.


Example 4: Generate a multiplication table

Classic nested loop use case, but still very practical for formatting.

for iinrange(1,6):
for jinrange(1,6):
print(i * j, end="\t")
print()

Output:

1   2   3   4   5
2   4   6   8   10
3   6   9   12  15
4   8   12  16  20
5   10  15  20  25

Outer loop controls the row number, inner loop prints the values inside that row.


Example 5: Searching for a value in a matrix

If you want to locate an item and stop when you find it, nested loops work fine, but you need the right exit strategy.

matrix = [
    [3,5,7],
    [2,9,1],
    [8,4,6]
]

target =9
found =False

for r, rowinenumerate(matrix):
for c, valueinenumerate(row):
if value == target:
print(f"Found {target} at row{r}, column{c}")
            found =True
break
if found:
break

Output:

Found9 atrow1,column1

break exits only the inner loop, so we used a found flag to stop the outer loop too.


Learn More About Nested Loops

Nested loops are powerful, but they also come with some “gotchas.” Once you know them, you’ll use nested loops with way more confidence.

A nested loop runs more times than you expect

A quick mental trick helps:

  • Outer loop runs A times
  • Inner loop runs B times for each outer run
  • Total inner operations = A * B

Example:

for iinrange(3):
for jinrange(4):
print(i, j)

Total prints: 3 * 4 = 12

So if your loops grow to 1,000 and 1,000, you’re suddenly doing 1,000,000 operations.

That’s why nested loops can feel “fine” at first, then suddenly slow later.


break and continue inside nested loops

These two keywords behave differently depending on where they appear.

break

break exits the loop it’s inside. That means:

  • If it’s inside the inner loop, it breaks only the inner loop
  • The outer loop continues to the next iteration

Example:

for xinrange(3):
for yinrange(3):
if y ==1:
break
print(x, y)

Output:

0 0
1 0
2 0

The inner loop stops at y == 1, but the outer loop keeps going.

continue

continue skips the rest of the current iteration of that loop.

for xinrange(2):
for yinrange(3):
if y ==1:
continue
print(x, y)

Output:

0 0
0 2
1 0
1 2

Only the y == 1 iteration is skipped.


A clean way to exit both loops

Using a flag works, but sometimes you want something cleaner.

One option is to wrap your logic in a function and return early.

deffind_value(matrix, target):
for r, rowinenumerate(matrix):
for c, valueinenumerate(row):
if value == target:
return r, c
returnNone

matrix = [
    [1,2],
    [3,4]
]

print(find_value(matrix,4))# (1, 1)

The return exits immediately, so you don’t need flags at all.


Nested loops with zip()

Sometimes two lists represent “pairs,” and you don’t actually need nesting.

Example: matching names and scores.

You might think to compare every name to every score, but you want them aligned:

names = ["Amina","Leo","Sofia"]
scores = [88,92,75]

for name, scoreinzip(names, scores):
print(name, score)

This avoids nested loops completely.


Nested loops vs list comprehensions

Sometimes, a nested loop is easiest to read.

But for building lists, a list comprehension can be shorter.

Example: flattening a list of lists.

Nested loop version:

nested = [[1,2], [3,4], [5]]
flat = []

for rowin nested:
for valuein row:
        flat.append(value)

print(flat)# [1, 2, 3, 4, 5]

List comprehension version:

nested = [[1,2], [3,4], [5]]
flat = [valuefor rowin nestedfor valuein row]
print(flat)# [1, 2, 3, 4, 5]

Both are fine. Use the one that feels clearer.


Nested loops with dictionaries

Dictionaries often hold nested structures too, like this:

orders = {
"Amina": ["book","pen"],
"Leo": ["notebook"],
"Sofia": ["pen","pencil","eraser"]
}

for customer, itemsin orders.items():
for itemin items:
print(f"{customer} ordered{item}")

You get clean output without complex logic.


The “too slow” moment and what to do about it

Nested loops are easy, but they can be slow when:

  • lists are large
  • comparisons happen too often
  • you scan the same data repeatedly

Common fixes:

  • Use a set for faster membership checks (in is faster in a set than a list)
  • Use break to stop early when possible
  • Use a dictionary lookup instead of scanning every time
  • Replace nested comparisons with indexing or grouping

Here’s a quick example of speeding up a membership check:

Slow approach:

list_a = [1,2,3,4]
list_b = [3,4,5,6]

for ain list_a:
for bin list_b:
if a == b:
print("Match:", a)

Faster approach:

list_a = [1,2,3,4]
list_b = [3,4,5,6]

set_b =set(list_b)

for ain list_a:
if ain set_b:
print("Match:", a)

Same result, fewer steps.


Summary

Nested loops in Python let you repeat work across two (or more) levels of data, like rows and columns, categories and items, or students and grades. They’re great for grids, nested lists, comparisons, and structured output.

Once you understand how the inner loop runs fully for each outer loop step, you’ll spot nested loop patterns everywhere, and you’ll know when to keep them or replace them with something faster.