Python – Theory 4 — THE for LOOP



The for Loop. Repetition Made Easy.

The for Loop

Repetition Made Easy  |  Making Computers Do the Repetitive Work

🔁 Why Do We Need Loops?

One of the greatest advantages of computers over humans is their ability to repeat the same actions many times, quickly and without getting tired.

Imagine you need to print "Hello" 100 times. Without loops, you would have to write:

print("Hello")
print("Hello")
# ... 98 more times ...

This is tedious, error-prone, and impractical. Loops solve this problem.

Example 1: Without a Loop vs With a Loop

Without a loop:

print("Hello")
print("Hello")
print("Hello")
print("Hello")
print("Hello")

With a loop:

for _ in range(5):
    print("Hello")

Key takeaways:

  • Loops eliminate code duplication.
  • Loops are essential for handling repetitive tasks.

Interesting fact: The first programming languages with loops appeared in the 1950s. Before that, programmers had to write each instruction separately!

⚙️ for Loop – Basic Structure

for variable in range(n):
    # code block – repeats n times
  • for — keyword (lowercase).
  • variable — loop variable (takes different values).
  • in — keyword.
  • range(n) — generates numbers 0 to n-1.
  • : — colon (required).
  • Indented block — the loop body.
Example 2: Your First for Loop
for i in range(10):
    print("Hello")

Output:

Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello

Key takeaways:

  • range(10) means «repeat 10 times».
  • The loop variable i is not used here.

Interesting fact: The for loop in Python is different from for loops in languages like C or Java — it’s more like a «for each» loop.



🔢 The Loop Variable

The loop variable takes a different value during each iteration of the loop.

Example 3: The Loop Variable in Action
for i in range(5):
    print(i)

Output:

0
1
2
3
4

What happens:

  • Iteration 1: i = 0
  • Iteration 2: i = 1
  • Iteration 3: i = 2
  • Iteration 4: i = 3
  • Iteration 5: i = 4

Key takeaways:

  • The loop variable changes with each iteration.
  • range(n) produces values from 0 to n-1.

Interesting fact: Zero-based indexing comes from C and is used in many programming languages. It makes certain calculations easier.

Example 4: Using the Loop Variable
for i in range(5):
    print(i + 1, "-- Hello")

Output:

1 -- Hello
2 -- Hello
3 -- Hello
4 -- Hello
5 -- Hello

Here, i + 1 gives us numbers from 1 to 5.



🏷️ Naming the Loop Variable

Traditionally, loop variables are named i, j, or k (short for «index»). However, you can use any valid variable name.

Example 5: Traditional vs Descriptive Names

Traditional names:

for i in range(5):
    print(i)
 
for j in range(5):
    print(j)
 
for k in range(5):
    print(k)

Descriptive names:

for number in range(5):
    print(number)
 
for student in range(30):
    print("Student", student + 1)

Key takeaways:

  • Choose names that make your code readable.
  • i, j, k are conventional for simple loops.

📌 When You Don’t Need the Loop Variable

Sometimes you don’t need the loop variable at all — you just want to repeat an action. In this case, use the underscore _ as a «throwaway» variable.

Example 6: Using Underscore

Using i even though it’s not needed:

for i in range(5):
    print("Hello")

Better — using _ for throwaway variable:

for _ in range(5):
    print("Hello")

Key takeaways:

  • Use _ when you don’t need the loop variable.
  • This makes your intention clear.



📏 The range() Function – One Parameter

Formula: range(n) → 0, 1, 2, …, n-1

  • Starts at 0.
  • Stops before n.
  • Generates exactly n numbers.
Example 7: Print Numbers from 0 to 9

Task: Write a program that prints all numbers from 0 to 9, each on a new line.

for i in range(10):
    print(i)

Output:

0
1
2
3
4
5
6
7
8
9

Step-by-step explanation:

  1. range(10) generates numbers 0 through 9.
  2. Each iteration takes the next value.
  3. print(i) displays the current value.

Key takeaways:

  • range(n) generates numbers from 0 to n-1.
  • The stop value is not included.



📐 range() – Two Parameters

Formula: range(start, stop) → start, start+1, …, stop-1

Example 8: range(3, 10)
for i in range(3, 10):
    print(i)

Output:

3
4
5
6
7
8
9

Key takeaways:

  • You can control where the sequence starts.
  • The stop value is still exclusive.
Example 9: Print Numbers from 1 to 10

Task: Write a program that prints all numbers from 1 to 10, each on a new line.

for i in range(1, 11):
    print(i)

Step-by-step explanation:

  1. range(1, 11) generates numbers 1 through 10.
  2. The stop value (11) is exclusive.
  3. Each iteration prints i.



📈 range() – Three Parameters (Step)

Formula: range(start, stop, step) → start, start+step, start+2*step, …

Example 10: Using Step
for i in range(3, 10, 2):
    print(i)

Output:

3
5
7
9

More examples:

range(1, 10, 2)   # 1, 3, 5, 7, 9
range(2, 15, 3)   # 2, 5, 8, 11, 14
range(5, 30, 5)   # 5, 10, 15, 20, 25

Key takeaways:

  • The step parameter controls the increment.
  • Default step is 1.
Example 11: Print Even Numbers from 2 to 20

Task: Write a program that prints all even numbers from 2 to 20.

Solution:

for i in range(2, 21, 2):
    print(i)

Step-by-step explanation:

  1. range(2, 21, 2) generates 2, 4, 6, …, 20.
  2. Start at 2, stop before 21, step by 2.
  3. Each value is printed.

Alternative solution (using if):

for i in range(2, 21):
    if i % 2 == 0:
        print(i)



🔽 Negative Step – Counting Down

You can use a negative step to count downwards. When using a negative step, the start must be greater than the stop.

Example 12: Counting Down
for i in range(10, 3, -1):
    print(i)

Output:

10
9
8
7
6
5
4

Countdown example:

for i in range(5, 0, -1):
    print(i, end=" ")
print("Blast off!")

Output:

5 4 3 2 1 Blast off!

Key takeaways:

  • Negative step creates descending sequences.
  • Useful for countdowns and reverse iteration.



📋 range() Summary Table

Function Call Sequence Generated
range(5) 0, 1, 2, 3, 4
range(1, 5) 1, 2, 3, 4
range(3, 7) 3, 4, 5, 6
range(7, 3) (empty)
range(2, 15, 3) 2, 5, 8, 11, 14
range(9, 2, -1) 9, 8, 7, 6, 5, 4, 3
range(3, 10, -2) (empty)

Key takeaways:

  • range() is versatile with 1, 2, or 3 parameters.
  • The stop value is always exclusive.

Interesting fact: The range() function in Python 3 returns a range object, not a list. This makes it memory-efficient for large sequences.



🔧 Common Loop Patterns

📌 1. Counting — Using a Counter Variable

Often we need to count how many times something happens.

  1. Create a counter variable and set it to 0.
  2. Increase it by 1 each time a condition is met.
Example 13: Count Numbers Greater Than 10

Task: Write a program that reads 10 numbers and counts how many are greater than 10.

counter = 0
 
for i in range(10):
    num = int(input("Enter number " + str(i + 1) + ": "))
    if num > 10:
        counter = counter + 1
 
print("Count of numbers greater than 10:", counter)

Step-by-step explanation:

  1. Initialize counter = 0.
  2. Loop 10 times.
  3. Read a number each iteration.
  4. If the number is greater than 10, increment counter.
  5. Print the final count.

Key takeaway: The line counter = counter + 1 means: take the old value of counter, add 1, and store it back in counter. Always initialize counters before the loop.

📌 2. Calculating a Sum — Using an Accumulator

Accumulators build up a result over iterations. Start with the neutral element (0 for addition).

Example 14: Sum of Numbers from 1 to n

Task: Write a program that reads a number n and calculates the sum of all numbers from 1 to n.

n = int(input("Enter n: "))
total = 0
 
for i in range(1, n + 1):
    total = total + i
 
print("Sum of 1 to", n, ":", total)

Example run:

Enter n: 10
Sum of 1 to 10 : 55

Step-by-step explanation:

  1. Read n from the user.
  2. Initialize total = 0.
  3. Loop i from 1 to n.
  4. Add i to total each iteration.
  5. Print the final sum.

📌 3. Product — Accumulator for Multiplication

Products start with 1. Factorial is a classic example.

Example 15: Factorial

Task: Write a program that reads a number n and calculates n! (factorial).

n = int(input("Enter n: "))
factorial = 1
 
for i in range(1, n + 1):
    factorial = factorial * i
 
print(n, "! =", factorial)

Example run:

Enter n: 5
5 ! = 120

Test: For n = 5: 1 × 2 × 3 × 4 × 5 = 120

Step-by-step explanation:

  1. Read n from the user.
  2. Initialize factorial = 1 (neutral for multiplication).
  3. Loop i from 1 to n.
  4. Multiply factorial by i each iteration.
  5. Print the result.

📌 4. Finding Maximum and Minimum

Finding max/min is a common task. Start with the first element.

Example 16: Finding the Largest and Smallest Number

Maximum:

largest = int(input())   # assume first number is the largest
 
for _ in range(9):       # we already read one number
    num = int(input())
    if num > largest:
        largest = num
 
print("Largest number:", largest)

Minimum — use < instead of >:

smallest = int(input())  # assume first number is the smallest
 
for _ in range(9):
    num = int(input())
    if num < smallest:
        smallest = num
 
print("Smallest number:", smallest)

Step-by-step:

  1. Start with the first value as the maximum.
  2. Compare each subsequent value and update if larger.



🧩 Nested Loops – Loops Inside Loops

A loop can contain another loop inside it. This is called a nested loop. Nested loops are useful for creating patterns and grids.

Example 17: Basic Nested Loop
for i in range(3):
    for j in range(5):
        print("*", end="")
    print()

Output:

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

How it works:

  • Outer loop: 3 rows.
  • Inner loop: 5 stars per row.
  • Total iterations: 3 × 5 = 15.
Example 18: Star Triangle

Task: Create a triangle with height n using nested loops.

n = int(input())
 
for i in range(1, n + 1):
    for j in range(i):
        print("*", end="")
    print()

Example run (n = 5):

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

Step-by-step explanation:

  1. Read n from the user.
  2. Outer loop: i goes from 1 to n (rows).
  3. Inner loop: j goes from 0 to i-1 (stars in row).
  4. Each row has i stars.
  5. print() moves to the next line after each row.
Example 19: Star Rectangle

Task: Read n and print a rectangle of stars with n rows and 19 columns.

n = int(input("Enter n: "))
 
for _ in range(n):
    print("*" * 19)

Alternative (using nested loops):

n = int(input("Enter n: "))
 
for _ in range(n):
    for _ in range(19):
        print("*", end="")
    print()



⚠️ Common Mistakes and Best Practices

📌 1. Forgetting the Colon

Example 20: Missing Colon

Wrong:

for i in range(5)   # Missing colon!
    print(i)

Correct:

for i in range(5):
    print(i)

📌 2. Incorrect Indentation

Example 21: Indentation Errors

Wrong — print is outside the loop:

for i in range(5):
    print("Hello")
print("World")   # This runs only once!

Correct — both lines are in the loop:

for i in range(5):
    print("Hello")
    print("World")

📌 3. Off-by-One Errors

Remember that range(n) stops at n-1.

Example 22: Off-by-One
# Prints 0 to 4, NOT 1 to 5
for i in range(5):
    print(i)
 
# Correct: use range(1, 6)
for i in range(1, 6):
    print(i)

📌 4. Forgetting to Initialize Counters / Sums

Example 23: Uninitialized Counter

Wrong — counter is not initialized:

for _ in range(5):
    counter = counter + 1   # NameError!

Correct:

counter = 0
for _ in range(5):
    counter = counter + 1

📌 Best Practices

  1. Use descriptive variable names for clarity:
    for student_id in range(1, 31):
        print("Student", student_id)

  2. Use _ when you don't need the loop variable:
    for _ in range(10):
        print("Hello")

  3. Keep loop bodies small and focused — if a loop is getting long, consider moving code to a function.
  4. Be careful with range() bounds — remember that the stop value is exclusive.