Free Study Material
Iterative statements, or loops, repeat a block of statements. Python has two: the while loop, which repeats as long as a condition stays True, and the for loop, which runs once for each item in a sequence such as a range(), a string or a list. Selection chooses between paths that each run once; iteration lets a block run again and again. We begin with the while loop.
while condition:
statement(s)
Python checks condition before each pass through the loop. As long as it's True, the indented block runs, then Python checks the condition again. The moment it's False, the loop stops, and the program continues with whatever comes after it.
Something inside the loop body must eventually make condition False — usually by updating a counter variable each pass. If nothing ever does, the loop never stops: an infinite loop.
count = 1
while count <= 5:
print("Count is:", count)
count += 1
print("Loop finished.")
count starts at 1. Each pass prints its current value, then count += 1 increases it by one. Python checks count <= 5 before every pass: it's True for count = 1, 2, 3, 4, 5 — five passes total — and False once count becomes 6, which is when the loop stops. Loop finished. then prints exactly once, after the loop ends.
Warning: Removing thecount += 1line would makecondition(count <= 5)Trueforever, sincecountwould always stay1— the loop would never stop. Always double-check that awhileloop's body genuinely moves its condition towardFalse.
A while loop is the right choice specifically when you don't know in advance exactly how many times a loop needs to run — only the condition under which it should keep going. When the exact number of repetitions is already known ahead of time, the next topic's for loop is usually the more natural fit.
while condition: repeats its indented block for as long as condition stays True, checking it before every pass — the loop body must eventually make the condition False (typically by updating a counter), or the loop runs forever as an infinite loop.
The while loop is a control flow statement that allows code to be executed repeatedly based on a given Boolean condition. It is often called a "Condition-Controlled Loop" because it runs while a specific condition remains True.
x > 0) that returns True or False.x = x - 1) to eventually stop the loop.
# Program to simulate a Password Check
# 1. Initialization
correct_password = "KVCODERS"
user_attempt = "WRONG_PASS" # Simulating a wrong guess initially
print("System Locked.")
# 2. Condition: Keep running while the attempt is WRONG
while user_attempt != correct_password:
print("Attempt:", user_attempt)
print("Access Denied. Trying again...")
# 3. Update: Simulate the user typing the correct password
# In a real app, this would be: input("Enter Password: ")
user_attempt = "KVCODERS"
print("Access Granted! Welcome User.")
while repeats based on a condition you check yourself. When you already know exactly how many times something should repeat, Python's for loop — paired with range() — is the more natural, more common choice.
for variable in range(...):
statement(s)
range() generates a sequence of whole numbers, and for runs its block once for each number in that sequence, storing the current one in variable each time. range() has three forms:
0, 1, 2, ... stop-1 (starts at 0, stops one before stop).start, start+1, ... stop-1.step each time instead of by 1.for i in range(5):
print("i is:", i)
for num in range(2, 11, 2):
print("Even number:", num)
range(5) generates 0, 1, 2, 3, 4 — five values, stopping one before 5 — so the first loop prints i is: 0 through i is: 4, five lines total. range(2, 11, 2) starts at 2, stops one before 11, and counts up by 2 each time: 2, 4, 6, 8, 10 — so the second loop prints five lines of even numbers, ending at 10.
Note:range(stop)never includesstopitself.range(5)produces five values (0through4), not six — a detail that causes a common off-by-one mistake.
range()'s "stops one before the given number" rule feels unusual at first, but it directly matches how counting positions normally works in programming: range(len(some_sequence)) (covered once sequences like strings and lists are introduced) produces exactly the valid index positions of that sequence, with no extra, out-of-range value ever included.
for variable in range(...): repeats its block once for each number range() generates, storing the current value in variable each pass. range(stop) counts from 0; range(start, stop) sets a custom start; range(start, stop, step) also sets the counting increment — and stop itself is never included in any form.
The for loop is used to iterate over a sequence. In Class 11 CS, we primarily use it with the range() function, which generates a specific sequence of numbers for the loop to follow.
| Syntax | Explanation | Example |
range(stop) |
Starts at 0. Stops before the stop value. Increases by 1. |
range(3)Output: 0, 1, 2 |
range(start, stop) |
Starts at start. Stops before the stop value. |
range(2, 5)Output: 2, 3, 4 |
range(start, stop, step) |
Starts at start. Jumps by step value. |
range(1, 10, 2)Output: 1, 3, 5, 7, 9 |
Critical Rule: The stop value is NEVER included in the sequence. It is the "Finish Line"—you stop the moment you touch it.
# 1. ONE ARGUMENT: range(stop)
# Python assumes start=0, step=1
print("--- range(5) ---")
for i in range(5):
print(i, end=" ")
print() # New line
# 2. TWO ARGUMENTS: range(start, stop)
# Python assumes step=1
print("\n--- range(10, 15) ---")
for j in range(10, 15):
print(j, end=" ")
print()
# 3. THREE ARGUMENTS: range(start, stop, step)
# We define everything. Note the output stops before 11.
print("\n--- range(1, 11, 2) ---")
for k in range(1, 11, 2):
print(k, end=" ")
print()
# 4. NEGATIVE STEP: Counting Down
print("\n--- range(5, 0, -1) ---")
for l in range(5, 0, -1):
print(l, end=" ")
Both loops you've seen run their entire body every pass, and stop only when their condition or range is exhausted. Sometimes a loop needs to exit early, or skip just one pass without stopping — that's what break and continue are for.
for num in range(1, 11):
if num == 6:
break
print("break demo:", num)
for num in range(1, 11):
if num % 2 == 0:
continue
print("continue demo:", num)
The first loop prints break demo: for 1 through 5. The moment num becomes 6, break exits the loop entirely — 6 through 10 are never even checked, and no further lines print.
The second loop checks every number from 1 to 10. Whenever num % 2 == 0 (an even number), continue skips straight to the next pass, so that print() line never runs for it. The loop still visits every number — it just prints only the odd ones: 1, 3, 5, 7, 9.
Note:breakstops the loop.continuedoes not stop the loop — it only skips ahead to the next pass. Confusing the two is a common exam mistake.
The difference is really about scope: break affects the whole loop (ending it), while continue affects only the current pass (ending just that one iteration early). Tracing both examples by hand — writing down exactly which numbers get printed — is the fastest way to make this distinction automatic.
break exits a loop immediately and entirely, skipping any remaining passes. continue skips only the rest of the current pass and moves on to the next one, without stopping the loop itself.
The break statement immediately terminates the loop. The control jumps to the very first line of code after the loop body. It is often used to stop a loop early when a specific item is found.
The continue statement skips the rest of the current iteration and jumps back to the top of the loop for the next round. It does not stop the loop; it just skips one turn.
# Program to process a list of numbers
# Goal: Stop if we find 99 (Emergency Stop)
# Goal: Skip any negative numbers (Invalid Data)
numbers = [10, -5, 20, -1, 99, 50]
print("Starting Process...")
for num in numbers:
# 1. Check for Emergency Stop
if num == 99:
print("Found 99! Stopping immediately.")
break # Exits the loop completely
# 2. Check for Skip
if num < 0:
print("Skipping negative number...")
continue # Skips print(num) and goes to next number
# This line is skipped if continue runs
# This line is never reached if break runs
print("Processing number:", num)
print("Loop Finished.")
| Feature | break | continue |
|---|---|---|
| Action | Terminates the loop entirely. | Skips current iteration only. |
| Next Step | Goes to code AFTER the loop. | Goes to the NEXT loop cycle. |
Just as an if can sit inside another if, a loop can sit inside another loop. This is the standard way to work through anything with two dimensions — like rows and columns of a pattern.
A nested loop is a loop placed inside the body of another loop. The inner loop runs completely — every one of its own passes — for each single pass of the outer loop. If the outer loop runs 3 times and the inner loop runs 4 times, the inner loop's body executes 3 × 4 = 12 times in total.
for row in range(1, 4):
for col in range(1, 4):
print("*", end=" ")
print()
The outer loop runs for row = 1, 2, 3 — three passes. For each of those, the inner loop runs completely, for col = 1, 2, 3 — printing on one line (end=" " keeps every on the same line instead of starting a new one each time). The plain print() after the inner loop — but still inside the outer loop — then moves to a new line, once per outer pass. The result is a 3×3 grid of stars:
* * *
* * *
* * *
Note: The plain print() is indented to match the outer loop's body, one level shallower than the inner loop — that placement is exactly what makes it run once per row, instead of once per star.
Indentation is what decides which loop a statement belongs to, and getting it wrong produces a completely different, often confusing result: indenting the final print() to match the inner loop instead would put a line break after every single star, destroying the row structure entirely — the same indentation rules from earlier in this unit apply here, just with two loops instead of one if.
A nested loop is a loop inside another loop's body — the inner loop runs completely for every single pass of the outer loop, which is the standard technique for working through two-dimensional patterns like a grid of rows and columns.
A Nested Loop is simply a loop inside the body of another loop. The loop that contains the other is called the Outer Loop, and the one inside is called the Inner Loop.
# Program to print a Square Pattern of Stars
# Syllabus: Generating Pattern
rows = 4
cols = 4
print("--- Start Pattern ---")
# Outer Loop: Controls the Rows (Vertical)
for i in range(rows):
# Inner Loop: Controls the Columns (Horizontal)
for j in range(cols):
print("*", end=" ") # Prints star without new line
print() # Moves to the next line after Inner Loop finishes
print("--- End Pattern ---")
This chapter covered while, for, break/continue, and nested loops individually. This closing topic puts them to work in a few complete, small programs — the kind of question this exact chapter is tested with.
number = 4321
original = number
total = 0
while number > 0:
digit = number % 10
total = total + digit
number = number // 10
print("Sum of digits of", original, "is", total)
Each pass strips off the last digit with % 10, adds it to total, then removes that digit with // 10 (both from the Data Types & Operators chapter). The loop naturally stops once number reaches 0. For 4321: digits 1, 2, 3, 4 are added one at a time, giving total = 10.
number = 17
is_prime = True
if number < 2:
is_prime = False
else:
for i in range(2, number):
if number % i == 0:
is_prime = False
break
if is_prime:
print(number, "is a prime number.")
else:
print(number, "is not a prime number.")
A number is prime only if nothing between 2 and itself divides it evenly. The loop tries every candidate divisor; the moment one divides number with no remainder (number % i == 0), is_prime is set to False and break exits immediately — there's no need to keep checking once a single divisor is found. For 17, no value of i from 2 to 16 divides it evenly, so the loop finishes normally and is_prime stays True.
Tip:breakinside theforloop is what makes this efficient — without it, the loop would keep checking every remaining value ofieven after already knowing the answer.
Both programs follow the same shape: a loop that processes one piece of data per pass (one digit, one candidate divisor), combined with a variable that carries a running result across passes (total, is_prime) — the core pattern behind nearly every loop-based program in this course from here on.
Sum of Digits repeatedly strips off and adds the last digit using % and // inside a while loop. Prime Number Check tries every possible divisor inside a for loop and uses break to stop as soon as one is found — both combine a loop with a running-result variable, the standard pattern for loop-based problems.
# Program to calculate Sum of Natural Numbers
# Syllabus: Summation of series
n = 10 # Change this value to test different limits
sum_total = 0 # Initialize sum variable
# Loop from 1 to n
for i in range(1, n + 1):
sum_total = sum_total + i
print("The sum of first", n, "numbers is:", sum_total)
# Program to find Factorial of a number
# Syllabus: Finding the factorial
num = 5 # Change to test (e.g., 3, 5, 7)
factorial = 1
if num < 0:
print("Factorial does not exist for negative numbers.")
elif num == 0:
print("Factorial of 0 is 1.")
else:
# Loop from 1 to num
for i in range(1, num + 1):
factorial = factorial * i
print("Factorial of", num, "is", factorial)
# Program to generate a Triangle Pattern
# Syllabus: Generating pattern
rows = 5
print("--- Triangle Pattern ---")
for i in range(1, rows + 1):
# Print 'i' stars in each row
print("*" * i)
When calculating a running total (Summation) or product (Factorial), we use an Accumulator Variable.