CyberStars

Nested Loops

We already know what a for loop does. But what happens if we put a loop inside another loop? This is called a nested loop and it's one of those things that seems confusing at first but becomes second nature once you see it in action

Let's start simple. We want to display all combinations of two dice rolls

for die1 in range(1, 7):
    for die2 in range(1, 7):
        print(f"{die1} {die2}")

This will print 36 lines: (1,1), (1,2), ..., (1,6), (2,1), (2,2), ... all the way to (6,6)

How does it work? The outer loop starts with die1 = 1. Then the inner loop runs completely from die2 = 1 to die2 = 6. After the inner loop finishes, the outer loop moves to die1 = 2, and the inner loop runs again from scratch. And so on

Think of it like a clock: the inner loop is the minute hand (goes fast, full rotation), the outer loop is the hour hand (moves only after the minute hand completes a full cycle)


A very common use: displaying a multiplication table

for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i} x {j} = {i * j}")
    print("---")

The print("---") is inside the outer loop but outside the inner loop, so it prints after each "row" of multiplications. Pay attention to the indentation, it matters a lot here


We can also use nested loops with lists

teams = ["Sharks", "Bears"]
players = ["Tommy", "Lance", "Cortez"]

for team in teams:
    for player in players:
        print(f"{player} plays for {team}")

Output

Tommy plays for Sharks
Lance plays for Sharks
Cortez plays for Sharks
Tommy plays for Bears
Lance plays for Bears
Cortez plays for Bears

Every player gets paired with every team. The outer loop picks a team, and the inner loop goes through all players for that team


break inside a nested loop only stops the inner loop, not the outer one

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

Output

1 1
2 1
3 1

When j hits 2, break stops the inner loop, but the outer loop keeps going to the next i


Printing on the same line with end=""

So far, every print() automatically moved to a new line after printing. We can change that with end

print("a", end="")
print("b", end="")
print("c")

Prints

abc

Normally, the three print() calls would put a, b, and c on separate lines. With end="" we tell print "don't move to a new line, leave the cursor right here". The last print("c") has no end="", so after it we do drop to the next line

This gets powerful together with nested loops: we can draw a shape row by row

for row in range(3):
    for star in range(3):
        print("*", end="")
    print()

Prints

***
***
***

Let's trace what happens:

  • the outer loop starts with row = 0
  • the inner loop prints * three times, all on the same line thanks to end="" → ***
  • after the inner loop, print() alone (empty) drops to the next line
  • the outer loop continues with row = 1, then row = 2, and it all repeats

The inner loop draws one full row, and the print() at the end drops to the next row


Mission: Signal Tower

Build a tower of stars for the station's antenna. Read from the user how many rows the tower has, then print a triangle: the first row has 1 star, the second 2, the third 3, and so on down to the last row

Example

If the user types

5

the program prints

*
**
***
****
*****