Lesson 6 of 2021 min read

Loops (for, while)

Share:WhatsAppLinkedIn

Prerequisites: Variables, Data Types, Operators, Input/Output, Conditional Statements


1. What Are Loops?

A loop repeats a block of code multiple times until a condition is met. Loops eliminate the need to write the same code over and over.

Without a loop (repetitive code):

print(1)
print(2)
print(3)
print(4)
print(5)

With a loop (clean code):

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

Both produce the same output: numbers 1 through 5.

Python has two types of loops: for and while.


2. The for Loop

The for loop iterates over a sequence (range, string, list, tuple, etc.) and executes the block once for each item.

Syntax

for variable in sequence:
 statement(s)

2.1 for Loop with range

The range function generates a sequence of numbers. It is the most common way to use for loops.

Three forms of range:

Form Meaning Example Numbers Generated
range(n) 0 to n-1 range(5) 0, 1, 2, 3, 4
range(start, stop) start to stop-1 range(1, 6) 1, 2, 3, 4, 5
range(start, stop, step) start to stop-1, step by step range(1, 10, 2) 1, 3, 5, 7, 9

Critical: range does NOT include the stop value.

# Example 1: range with one argument
for i in range(5): # 0, 1, 2, 3, 4
 print(i, end=" ")
print
# Output: 0 1 2 3 4

# Example 2: range with two arguments
for i in range(1, 6): # 1, 2, 3, 4, 5
 print(i, end=" ")
print
# Output: 1 2 3 4 5

# Example 3: range with three arguments (positive step)
for i in range(1, 10, 2): # 1, 3, 5, 7, 9
 print(i, end=" ")
print
# Output: 1 3 5 7 9

# Example 4: range with negative step (counting down)
for i in range(10, 0, -1): # 10, 9, 8, ..., 1
 print(i, end=" ")
print
# Output: 10 9 8 7 6 5 4 3 2 1

# Example 5: range with step of -2
for i in range(20, 0, -2): # 20, 18, 16, ..., 2
 print(i, end=" ")
print
# Output: 20 18 16 14 12 10 8 6 4 2

Output:

0 1 2 3 4
1 2 3 4 5
1 3 5 7 9
10 9 8 7 6 5 4 3 2 1
20 18 16 14 12 10 8 6 4 2

Common mistake with range:

# This generates NOTHING (start > stop with positive step)
for i in range(5, 1):
 print(i)
# No output! Must use range(5, 1, -1) to count down.

# This also generates nothing
for i in range(1, 5, -1):
 print(i)
# No output! Negative step but start < stop.

2.2 for Loop with Strings

# Example 6: Iterating over a string
word = "Python"
for ch in word:
 print(ch, end=" ")
print
# Output: P y t h o n

# Example 7: Count vowels in a string
text = "Hello World"
count = 0
for ch in text:
 if ch.lower in "aeiou":
 count += 1
print(f"Number of vowels: {count}")
# Output: Number of vowels: 3

2.3 for Loop with Lists and Tuples

# Example 8: Iterating over a list
fruits = ["apple", "banana", "cherry", "date"]
for fruit in fruits:
 print(fruit)
# Output:
# apple
# banana
# cherry
# date

# Example 9: Sum of elements in a list
numbers = [10, 20, 30, 40, 50]
total = 0
for num in numbers:
 total += num
print(f"Sum = {total}")
# Output: Sum = 150

# Example 10: Iterating over a tuple
colors = ("red", "green", "blue")
for color in colors:
 print(color.upper)
# Output:
# RED
# GREEN
# BLUE

3. The while Loop

The while loop repeats a block of code as long as a condition remains True. You must manually update the loop variable to avoid an infinite loop.

Syntax

while condition:
 statement(s)
 # update loop variable!
# Example 11: Basic while loop - print 1 to 5
i = 1 # initialization
while i <= 5: # condition
 print(i, end=" ")
 i += 1 # update (VERY IMPORTANT!)
print
# Output: 1 2 3 4 5
# Example 12: Countdown
count = 5
while count > 0:
 print(count, end=" ")
 count -= 1
print("Go!")
# Output: 5 4 3 2 1 Go!
# Example 13: Sum until user enters 0
total = 0
num = int(input("Enter a number (0 to stop): "))

while num != 0:
 total += num
 num = int(input("Enter a number (0 to stop): "))

print(f"Total = {total}")

Output:

Enter a number (0 to stop): 10
Enter a number (0 to stop): 20
Enter a number (0 to stop): 30
Enter a number (0 to stop): 0
Total = 60

Infinite Loop Warning

If the loop condition never becomes False, the loop runs forever. This is called an infinite loop.

# DANGER: Infinite loop (missing update!)
# i = 1
# while i <= 5:
# print(i)
# # FORGOT i += 1 - this will print 1 forever!

# Press Ctrl+C to stop an infinite loop in the terminal

for vs while: When to Use Which

Use for when... Use while when...
Number of iterations is known Number of iterations is unknown
Iterating over a sequence Repeating until a condition changes
Counting from A to B Waiting for user input
Processing each element Game loops, menus

4. The break Statement

break terminates the loop immediately. Control jumps to the first statement after the loop.

# Example 14: break in a for loop
for i in range(1, 11):
 if i == 6:
 break # exit the loop when i is 6
 print(i, end=" ")
print
print("Loop ended")
# Output: 1 2 3 4 5
# Loop ended
# Example 15: break in a while loop - search for a value
numbers = [4, 7, 2, 9, 1, 8, 3]
target = 9
found = False

for num in numbers:
 if num == target:
 found = True
 break # stop searching once found

if found:
 print(f"{target} found in the list!")
else:
 print(f"{target} not found.")
# Output: 9 found in the list!
# Example 16: break to exit on user command
while True: # infinite loop
 text = input("Type something (or 'quit' to exit): ")
 if text.lower == "quit":
 break # exit the infinite loop
 print(f"You typed: {text}")

print("Goodbye!")

Output:

Type something (or 'quit' to exit): Hello
You typed: Hello
Type something (or 'quit' to exit): Python
You typed: Python
Type something (or 'quit' to exit): quit
Goodbye!

5. The continue Statement

continue skips the rest of the current iteration and jumps to the next iteration of the loop.

# Example 17: continue - skip even numbers
for i in range(1, 11):
 if i % 2 == 0:
 continue # skip even numbers
 print(i, end=" ")
print
# Output: 1 3 5 7 9
# Example 18: continue - skip negative numbers while summing
numbers = [10, -5, 20, -3, 15, -8, 25]
total = 0

for num in numbers:
 if num < 0:
 continue # skip negative numbers
 total += num

print(f"Sum of positive numbers: {total}")
# Output: Sum of positive numbers: 70

break vs continue

Feature break continue
Action Exits the entire loop Skips current iteration
Loop continues? No Yes (next iteration)
Code after it (in loop) Not executed Not executed (for current iteration)
# Example 19: break vs continue side by side
print("Using break:")
for i in range(1, 6):
 if i == 3:
 break
 print(i, end=" ")
print
# Output: 1 2

print("Using continue:")
for i in range(1, 6):
 if i == 3:
 continue
 print(i, end=" ")
print
# Output: 1 2 4 5

Output:

Using break:
1 2
Using continue:
1 2 4 5

6. The pass Statement

pass is a null statement, it does nothing. It is used as a placeholder where a statement is syntactically required but you do not want to execute anything.

# Example 20: pass as placeholder
for i in range(5):
 pass # TODO: implement later

# Without pass, an empty block would cause IndentationError:
# for i in range(5):
# # IndentationError: expected an indented block

# pass in if statement
x = 10
if x > 5:
 pass # will handle this later
else:
 print("x is small")

7. Nested Loops

A loop inside another loop. The inner loop completes all its iterations for each single iteration of the outer loop.

# Example 21: Nested loop - multiplication table layout
for i in range(1, 4): # outer loop: rows
 for j in range(1, 4): # inner loop: columns
 print(i * j, end="\t")
 print # newline after each row

Output:

1	2	3
2	4	6
3	6	9

How it works:

  • i=1: j goes 1, 2, 3 -> prints 1, 2, 3, i=2: j goes 1, 2, 3 -> prints 2, 4, 6, i=3: j goes 1, 2, 3 -> prints 3, 6, 9

Total iterations of inner loop: 3 x 3 = 9

Important: In nested loops, break only exits the innermost loop.

# Example 22: break in nested loop
for i in range(1, 4):
 for j in range(1, 4):
 if j == 2:
 break # exits only the inner loop
 print(f"({i},{j})", end=" ")
 print

Output:

(1,1)
(2,1)
(3,1)

8. Loop-else (Python Specific)

Python allows an else clause with for and while loops. The else block executes only when the loop completes normally (i.e., NOT terminated by break).

# Example 23: for-else (loop completes normally)
for i in range(1, 4):
 print(i, end=" ")
else:
 print("\nLoop completed normally!")

Output:

1 2 3
Loop completed normally!
# Example 24: for-else with break (else does NOT execute)
for i in range(1, 6):
 if i == 3:
 print("Breaking at 3!")
 break
 print(i, end=" ")
else:
 print("Loop completed normally!") # NOT executed because of break

print("After loop")

Output:

1 2 Breaking at 3!
After loop
# Example 25: Practical use of loop-else - check prime
num = int(input("Enter a number: "))

if num > 1:
 for i in range(2, num):
 if num % i == 0:
 print(f"{num} is NOT prime")
 break
 else:
 print(f"{num} is Prime") # only if loop completed without break
else:
 print(f"{num} is NOT prime")

Output (for input 7):

Enter a number: 7
7 is Prime

Output (for input 12):

Enter a number: 12
12 is NOT prime

Practice Programs

Program 1: Print 1 to N

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

Output (for N=10):

Enter N: 10
1 2 3 4 5 6 7 8 9 10

Program 2: Sum of N Natural Numbers

n = int(input("Enter N: "))
total = 0
for i in range(1, n + 1):
 total += i
print(f"Sum of first {n} natural numbers = {total}")

# Verification using formula: n*(n+1)/2
print(f"Using formula: {n * (n + 1) // 2}")

Output (for N=100):

Enter N: 100
Sum of first 100 natural numbers = 5050
Using formula: 5050

Program 3: Factorial of a Number

n = int(input("Enter a number: "))
factorial = 1

if n < 0:
 print("Factorial is not defined for negative numbers")
elif n == 0:
 print("Factorial of 0 = 1")
else:
 for i in range(1, n + 1):
 factorial *= i # factorial = factorial * i
 print(f"Factorial of {n} = {factorial}")

Output (for n=5):

Enter a number: 5
Factorial of 5 = 120

Trace (for n=5):

Iteration i factorial (before) factorial = factorial * i
1 1 1 1 * 1 = 1
2 2 1 1 * 2 = 2
3 3 2 2 * 3 = 6
4 4 6 6 * 4 = 24
5 5 24 24 * 5 = 120

Program 4: Fibonacci Series

The Fibonacci series: 0, 1, 1, 2, 3, 5, 8, 13, 21, ... (each number is the sum of the two preceding ones)

n = int(input("How many Fibonacci numbers? "))

a, b = 0, 1
print("Fibonacci Series:")
for i in range(n):
 print(a, end=" ")
 a, b = b, a + b # simultaneous assignment
print

Output (for n=10):

How many Fibonacci numbers? 10
Fibonacci Series:
0 1 1 2 3 5 8 13 21 34

Trace:

Iteration a (printed) b New a = b New b = a + b
0 0 1 1 0 + 1 = 1
1 1 1 1 1 + 1 = 2
2 1 2 2 1 + 2 = 3
3 2 3 3 2 + 3 = 5
4 3 5 5 3 + 5 = 8

Program 5: Check Prime Number

num = int(input("Enter a number: "))

if num <= 1:
 print(f"{num} is NOT prime")
else:
 is_prime = True
 for i in range(2, int(num ** 0.5) + 1): # check up to square root
 if num % i == 0:
 is_prime = False
 break
 
 if is_prime:
 print(f"{num} is Prime")
 else:
 print(f"{num} is NOT prime")

Output:

Enter a number: 29
29 is Prime
Enter a number: 100
100 is NOT prime

Why check only up to square root? If num = a * b, then at least one of a or b must be <= sqrt(num). So checking divisors up to sqrt(num) is sufficient.

Program 6: Reverse a Number

num = int(input("Enter a number: "))
original = num
reversed_num = 0

while num > 0:
 digit = num % 10 # extract last digit
 reversed_num = reversed_num * 10 + digit # append digit
 num = num // 10 # remove last digit

print(f"Original: {original}")
print(f"Reversed: {reversed_num}")

Output:

Enter a number: 12345
Original: 12345
Reversed: 54321

Trace (for num=1234):

Step num digit (num%10) reversed_num num after //10
1 1234 4 0*10 + 4 = 4 123
2 123 3 4*10 + 3 = 43 12
3 12 2 43*10 + 2 = 432 1
4 1 1 432*10 + 1 = 4321 0

Program 7: Check Palindrome Number

A number that reads the same forward and backward (e.g., 121, 1331, 12321).

num = int(input("Enter a number: "))
original = num
reversed_num = 0

while num > 0:
 digit = num % 10
 reversed_num = reversed_num * 10 + digit
 num = num // 10

if original == reversed_num:
 print(f"{original} is a Palindrome")
else:
 print(f"{original} is NOT a Palindrome")

Output:

Enter a number: 12321
12321 is a Palindrome
Enter a number: 12345
12345 is NOT a Palindrome

Program 8: Pattern Printing

Pattern 8a: Right Triangle with Stars

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

Pattern 8b: Number Triangle

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
n = int(input("Enter number of rows: "))
for i in range(1, n + 1):
 for j in range(1, i + 1):
 print(j, end=" ")
 print

Pattern 8c: Alphabet Triangle

A
A B
A B C
A B C D
A B C D E
n = int(input("Enter number of rows: "))
for i in range(1, n + 1):
 for j in range(i):
 print(chr(65 + j), end=" ") # chr(65) = 'A', chr(66) = 'B', etc.
 print

Pattern 8d: Inverted Triangle

* * * * *
* * * *
* * *
* *
*
n = int(input("Enter number of rows: "))
for i in range(n, 0, -1):
 for j in range(i):
 print("*", end=" ")
 print

Pattern 8e: Pyramid (Centered Triangle)

 *
 * * *
 * * * * *
 * * * * * * *
* * * * * * * * *
n = int(input("Enter number of rows: "))
for i in range(1, n + 1):
 # Print spaces
 print(" " * (n - i) * 2, end="")
 # Print stars
 for j in range(2 * i - 1):
 print("*", end=" ")
 print

Program 9: Multiplication Table

num = int(input("Enter a number: "))
print(f"\nMultiplication Table of {num}:")
print("-" * 20)
for i in range(1, 11):
 print(f"{num} x {i:2d} = {num * i}")

Output (for num=7):

Enter a number: 7

Multiplication Table of 7:
--------------------
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

Program 10: GCD and LCM

a = int(input("Enter first number: "))
b = int(input("Enter second number: "))
original_a, original_b = a, b

# GCD using Euclidean algorithm
while b != 0:
 a, b = b, a % b
gcd = a

# LCM = (original_a * original_b) / GCD
lcm = (original_a * original_b) // gcd

print(f"GCD of {original_a} and {original_b} = {gcd}")
print(f"LCM of {original_a} and {original_b} = {lcm}")

Output:

Enter first number: 12
Enter second number: 18
GCD of 12 and 18 = 6
LCM of 12 and 18 = 36

Trace of GCD (Euclidean algorithm) for a=12, b=18:

Step a b a % b New a New b
1 12 18 12 18 12
2 18 12 6 12 6
3 12 6 0 6 0

When b = 0, GCD = a = 6.

Program 11: Count Digits in a Number

num = int(input("Enter a number: "))
count = 0
temp = abs(num) # handle negative numbers

if temp == 0:
 count = 1
else:
 while temp > 0:
 count += 1
 temp //= 10

print(f"Number of digits in {num} = {count}")

Output:

Enter a number: 12345
Number of digits in 12345 = 5

Program 12: Sum of Digits

num = int(input("Enter a number: "))
total = 0
temp = abs(num)

while temp > 0:
 digit = temp % 10
 total += digit
 temp //= 10

print(f"Sum of digits of {num} = {total}")

Output:

Enter a number: 9876
Sum of digits of 9876 = 30

Trace (for num=9876):

Step temp digit (temp%10) total temp after //10
1 9876 6 0 + 6 = 6 987
2 987 7 6 + 7 = 13 98
3 98 8 13 + 8 = 21 9
4 9 9 21 + 9 = 30 0

Program 13: Armstrong Number Check

An Armstrong number (narcissistic number) is a number equal to the sum of its digits each raised to the power of the number of digits.

Examples: 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153

num = int(input("Enter a number: "))
original = num
n_digits = len(str(abs(num))) # count digits
total = 0

temp = abs(num)
while temp > 0:
 digit = temp % 10
 total += digit ** n_digits
 temp //= 10

if total == abs(num):
 print(f"{num} is an Armstrong number")
else:
 print(f"{num} is NOT an Armstrong number")

Output:

Enter a number: 153
153 is an Armstrong number
Enter a number: 9474
9474 is an Armstrong number
Enter a number: 123
123 is NOT an Armstrong number

Verification for 9474: 9^4 + 4^4 + 7^4 + 4^4 = 6561 + 256 + 2401 + 256 = 9474.

Program 14: Perfect Number Check

A perfect number is a number equal to the sum of its proper divisors (excluding itself).

Examples: 6 = 1 + 2 + 3, 28 = 1 + 2 + 4 + 7 + 14

num = int(input("Enter a number: "))
divisor_sum = 0

for i in range(1, num):
 if num % i == 0:
 divisor_sum += i

if divisor_sum == num:
 print(f"{num} is a Perfect number")
 # Also show the divisors
 divisors = []
 for i in range(1, num):
 if num % i == 0:
 divisors.append(str(i))
 print(f"Divisors: {' + '.join(divisors)} = {divisor_sum}")
else:
 print(f"{num} is NOT a Perfect number")

Output:

Enter a number: 28
28 is a Perfect number
Divisors: 1 + 2 + 4 + 7 + 14 = 28
Enter a number: 12
12 is NOT a Perfect number

Common Mistakes

  1. Off-by-one error with range: range(1, 5) gives 1, 2, 3, 4 (NOT 1 to 5). To include 5, use range(1, 6)
  2. Forgetting to update loop variable in while: Missing i += 1 inside a while loop causes infinite loop
  3. Indentation errors in loops: All loop body statements must be indented equally
  4. Using break thinking it exits all loops: In nested loops, break exits only the innermost loop
  5. Confusing break and continue: break exits the loop entirely; continue skips to the next iteration
  6. Forgetting the else in loop-else runs only without break: If break is executed, the else block is skipped
  7. Wrong range for counting down: range(5, 1) gives nothing. Must use range(5, 0, -1) to get 5, 4, 3, 2, 1
  8. Modifying a list while iterating over it: This can skip elements or cause unexpected behavior. Use a copy or build a new list
  9. Using = instead of == in while condition: while x = 5 is a SyntaxError. Use while x == 5
  10. Not handling edge cases: Programs should handle 0, negative numbers, and single-digit inputs correctly
  11. Integer division confusion in digit extraction: Always use // (not /) when extracting digits, since / returns float
  12. Forgetting that range returns an object, not a list: print(range(5)) prints range(0, 5), not [0, 1, 2, 3, 4]. Use list(range(5)) to see the numbers

$1$2 Quick Tips

  1. Find the output of loop code (2-4 marks): The most common question. Trace through each iteration carefully. Make a table of variable values
  2. Write a program (3-5 marks): Factorial, Fibonacci, prime check, palindrome, pattern printing, these appear almost every year
  3. Rewrite for as while (and vice versa) (2-3 marks): Know how to convert between loop types
  4. Pattern printing (3-4 marks): Practice at least 5 different patterns. The star triangle and number triangle are most common
  5. break vs continue (2 marks): Know the difference, give example of each, explain what happens to loop-else
  6. range output (1-2 marks): Given range(a, b, c), list the generated numbers
  7. Nested loop output (2-3 marks): Trace inner and outer loop iterations. Draw a table
  8. Loop-else (2 marks): Explain when else block runs. This is unique to Python and is a favorite exam topic
  9. Identify errors in loop code (1-2 marks): Missing colon, wrong range, missing update, wrong indentation
  10. Prime number and Fibonacci (3-5 marks): Memorize both programs. Understand the logic, not just the code
  11. Dry run / trace table (3-4 marks): Given a loop, fill in a table showing variable values at each iteration. Practice this skill
  12. "What is the purpose of pass?" (1 mark): Placeholder that does nothing; used when a statement is needed syntactically but no action is required

Test Your Knowledge

Take a quick quiz on this lesson

Start Quiz →

Prefer watching over reading?

Subscribe for free.

Subscribe on YouTube