Nested loops in Python


A nested loop has one loop inside of another. These are typically used for working with two dimensions such as printing stars in rows and columns as shown below. When a loop is nested inside another loop, the inner loop runs many times inside the outer loop. In each iteration of the outer loop, the inner loop will be re-started. The inner loop must finish all of its iterations before the outer loop can continue to its next iteration.

Example:

for row in range(3):
	for col in range(5):
		print("*", end='')
    print()

# This code prints a rectangle with 3 rows and 5 columns, filled with '*'
# We use print("*", end='') because print() prints with a trailing newline by default

Iterating through multidimensional arrays

Nested loops are also helpful when we want to iterate through a multi dimensional array, for example:

arr = [[1, 2], [3, 4], [5, 6]]

for i in range(len(arr)):
	for j in range(len(arr[i])):
		print(arr[i][j])

This outputs each sub-element in arr one at a time. Note that for the inner loop, we are using len(arr[i]), since arr[i] is itself an array.

Breaking nested loops

In a nested loop, a break statement only stops the loop it is placed in. Therefore, if a break is placed in the inner loop, the outer loop still continues. For example:

arr = [[1, 2], [3, 4], [5, 6]]

for i in range(len(arr)):
	for j in range(len(arr[i])):
		if arr[i][j] == 3:
			break
		print(arr[i][j])

# prints the numbers 1, 2, 5 and 6 on different lines

When i is 1 and j is 0, we execute the break. This means we stop the inner loop and go back to the outer loop to continue from the next iteration, which is i = 2. And as you can see, we print all the elements of row 2.

However, if the break is placed in the outer loop, all of the looping stops. For example:

arr = [[1, 2], [3, 4], [5, 6]]


for i in range(len(arr)):
	if arr[i][0] == 3:
		break
	for j in range(len(arr[i])):
		print(arr[i][j])
		
# prints the numbers 1 and 2 on different lines


Assignment
Follow the Coding Tutorial and let's write some nested loops.


Hint
Look at the examples above if you get stuck.


Introduction

Nested loops are a fundamental concept in programming, especially when dealing with multi-dimensional data structures or performing repetitive tasks within repetitive tasks. They are crucial for tasks such as matrix operations, image processing, and more. Understanding nested loops is essential for solving complex problems efficiently.

Understanding the Basics

At its core, a nested loop is simply a loop inside another loop. The outer loop controls the number of complete iterations, while the inner loop runs through its entire cycle for each iteration of the outer loop. This structure is particularly useful for working with grids, tables, or any two-dimensional data.

Consider the following simple example:

for i in range(3):
    for j in range(2):
        print(f"i: {i}, j: {j}")

In this example, the inner loop runs twice for each iteration of the outer loop, resulting in a total of 6 print statements.

Main Concepts

Let's break down the key concepts and techniques involved in nested loops:

Here's a more detailed example that prints a 3x3 grid of numbers:

for row in range(3):
    for col in range(3):
        print(f"({row}, {col})", end=' ')
    print()

This code will output:

(0, 0) (0, 1) (0, 2) 
(1, 0) (1, 1) (1, 2) 
(2, 0) (2, 1) (2, 2)

Examples and Use Cases

Nested loops are particularly useful in scenarios such as:

Consider the following example of iterating through a 2D list (matrix):

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

for row in matrix:
    for element in row:
        print(element, end=' ')
    print()

This code will output each element of the matrix in a grid format.

Common Pitfalls and Best Practices

When working with nested loops, it's important to avoid common mistakes such as:

Best practices include:

Advanced Techniques

Advanced techniques with nested loops include:

For example, using break in a nested loop:

for i in range(3):
    for j in range(3):
        if i == j:
            break
        print(f"i: {i}, j: {j}")

Code Implementation

Here's a comprehensive example that demonstrates the use of nested loops to print a multiplication table:

# Function to print multiplication table
def print_multiplication_table(size):
    for i in range(1, size + 1):
        for j in range(1, size + 1):
            print(f"{i * j:4}", end=' ')
        print()

# Print a 5x5 multiplication table
print_multiplication_table(5)

This code will output a formatted 5x5 multiplication table.

Debugging and Testing

When debugging nested loops, consider the following tips:

For testing, write test cases that cover different scenarios, such as edge cases and typical use cases. For example:

def test_multiplication_table():
    # Test a 2x2 table
    assert print_multiplication_table(2) == "  1   2\n  2   4\n"
    # Test a 3x3 table
    assert print_multiplication_table(3) == "  1   2   3\n  2   4   6\n  3   6   9\n"

test_multiplication_table()

Thinking and Problem-Solving Tips

When approaching problems involving nested loops:

Conclusion

Mastering nested loops is essential for tackling complex problems in programming. By understanding the basics, avoiding common pitfalls, and practicing regularly, you can become proficient in using nested loops effectively. Keep exploring and applying these concepts to real-world scenarios to enhance your problem-solving skills.

Additional Resources

For further reading and practice, consider the following resources: