2.2. Control Structures#
The three fundamental control structures in computer programming, dictating the order in which instructions are executed within a program, are:
Sequence logic (sequential flow)
Selection logic (conditional flow)
Iteration logic (repetitive flow)
As a fundamental concept, programming languages execute statements sequentially by default. Lines of instructions are executed in a defined sequential order unless selection/conditional statements (if/elif/else), iteration statements (for/while loops).
In addition to conditional and iteration, there are other loop control tools such as
Loop control statements (break, continue) to exit or skip iterations.
Function control (return) to exit a function early.
Exceptions (try/except/raise) to handle or redirect error flow.
Below are examples of conditions and decision-making with if, elif, and else.
2.2.1. Conditional Statements#
The main topic of conditionals is the if statement, which executes different code depending on the program’s state. if is a Python keyword. if statements have the same structure as function definitions: a
header followed by an indented statement or sequence of statements called a block.
The boolean expression after if is called the condition.
If it is true, the statements in the indented block run. If not, they don’t.
There is no limit to the number of statements that can appear in the block, but there has to be at least one. Occasionally, it is useful to have a block that does nothing – usually as a placeholder for code you haven’t written yet.
In that case, you can use the pass statement, which does nothing.
To write useful programs, we almost always need the ability to check conditions and adjust the program’s behavior accordingly, which involves:
boolean expressions for
True/Falsedecision, andlogical operators for combining Boolean expressions.
Python uses if statements to handle conditional logic, offering several structures to control program flow:
conditional execution (
if),alternative execution (
if/else),chained execution (
if/elif/else),nested conditions, and
the
matchStatement*
*not covered presently
2.2.1.1. Boolean Expressions#
A boolean expression is an expression that is either True or False.
For example, the following expressions use the equals operator, ==, which compares two values and produces True if they are equal and False otherwise. Remember that there are six relational/comparison operators: == != > < >= <=.
t_f_1 = 5 == 5
t_f_2 = 5 == 7
print(t_f_1, t_f_2)
True False
A common error is to use a single equal sign (=) instead of a double equal sign (==).
Remember that = assigns a value to a variable and == compares two values.
x = 5 ### assignment
y = 7 ### assignment
x == y ### comparison/relational
False
True and False are special values that belong to the type bool;
they are not strings:
print(type(True))
print(type(False))
<class 'bool'>
<class 'bool'>
The == operator is one of the 6 relational operators; the others are:
x != y # x is not equal to y
x > y # x is greater than y
x < y # x is less than y
x >= y # x is greater than or equal to y
x <= y # x is less than or equal to y
True
2.2.1.2. Logical operators#
To combine boolean values into expressions, we can use logical operators.
The most common are and, or, and not.
The meaning of these operators is similar to their meaning in English.
For example, the value of the following expression is True only if x is greater than 0 and less than 10.
x > 0 and x < 10
True
The following expression is True if either or both of the conditions is true, that is, if the number is divisible by 2 or 3:
x % 2 == 0 or x % 3 == 0
False
Finally, the not operator negates a boolean expression, so the following expression is True if x > y is False.
not x > y
True
Strictly speaking, the operands of a logical operator should be boolean expressions, but Python is not very strict.
Any nonzero number is interpreted as True (truthy):
42 and True
True
This flexibility can be useful, but there are some subtleties to it that can be confusing. You might want to avoid it.
2.2.1.3. Conditional execution (if)#
Conditional gives us the ability to check the conditions and is the simplest form of the if statement:
if x > 0:
print('x is positive')
x is positive
if x < 0:
pass # TODO: need to handle negative values!
The word TODO in a comment is a conventional reminder that there’s something you need to do later. Modern IDE’s would recognize it and act accordingly.
2.2.1.4. Alternative Execution (else)#
An if statement can have a second part, called an else clause. If the condition is true, the first indented statement runs; otherwise, the second indented statement runs. For example:
num = 42 ### can replace with: num = int(input("Please enter an integer: "))
if num % 2 == 0: ### % modulus operator
print("num is even")
else:
print("num is odd")
num is even
In this example, if num is even, the remainder when num is divided by 2 is 0, so the condition is True and the program displays num is even.
If num is odd, the remainder is 1, so the condition is false, and the program displays num is odd.
Since the condition must be true or false, exactly one of the alternatives will run. The alternatives are called branches.
2.2.1.5. Chained Conditional (elif)#
Sometimes there are more than two possibilities, and we need more than two branches. One way to express a computation like that is a chained conditional, which includes an elif clause.
elif is an abbreviation of “else if” and is used to add multiple conditions inside an if block. There is no limit on the number of elif clauses.
If there is an else clause, it has to be at the end, but there doesn’t have to be one.
Note that:
Each condition is checked in order.
If the first is false, the next is checked, and so on.
If one of them is true, the corresponding branch runs, and the
ifstatement ends.Even if more than one condition is true, only the first true branch runs.
x = 7 ### sample value to classify
if x > 10:
print("x is large") ### runs only when x is greater than 10
elif x > 5:
print("x is medium") ### runs when x is 6–10
else:
print("x is small") ### runs when x is 5 or less
x is medium
num = 7 # try different values
if num > 0:
print("positive")
elif num == 0:
print("neither positive nor negative")
elif num < 0:
print("negative")
positive
2.2.1.6. Nested Conditionals#
One conditional can also be nested within another. We could have written a conditional to compare two numbers:
print(f"x: {x}; y: {y}")
if x == y:
print('x and y are equal')
else:
if x < y:
print('x is less than y')
else:
print('x is greater than y')
x: 7; y: 7
x and y are equal
In this example, the outer if statement contains two branches:
The first branch contains a simple statement.
The second branch contains another
ifstatement with two branches of its own.
Those two branches are both simple print statements, although they could have been conditional statements as well.
Although the indentation of the statements makes the structure apparent, nested conditionals can be difficult to read. I suggest you avoid them whenever possible.
Logical operators often simplify nested conditional statements. Here’s an example with a nested conditional.
if 0 < x:
if x < 10:
print('x is a positive single-digit number.')
x is a positive single-digit number.
The print statement runs only if we make it past both conditionals, so we get the same effect with the and operator.
if 0 < x and x < 10:
print('x is a positive single-digit number.')
x is a positive single-digit number.
For this kind of condition, Python provides a more concise option:
if 0 < x < 10:
print('x is a positive single-digit number.')
x is a positive single-digit number.
2.2.2. while Loops#
A Python while loop repeatedly executes a block of code as long as a specified condition remains true. Once the condition evaluates to false, the program continues with the statement following the loop.
The syntax of Python while loop is:
while condition:
<body>
where
while: is the keyword that begins the loop header.
condition is an expression evaluated for truthiness that defines the exit condition.
consists of one or more statements to execute in each iteration.
As a general rule:
Use
whilewhen you don’t know how many times the loop will run in advance (e.g., processing until input validation succeeds, or until a condition becomes true).Use
forwhen you know the number of iterations upfront or are iterating through a sequence (list, string, range, etc.), or looping through a file.
Although all condition-based, there are several common patterns of while loops:
Type |
Also Called |
Condition Location |
Key Feature |
Use Case |
|---|---|---|---|---|
Condition-Controlled |
Standard |
At the top (header) |
Repeats while a condition is |
When you know the exit condition upfront |
Count-Controlled |
Counter |
At the top (header) |
Uses incrementing/decrementing counter variable |
When you know how many iterations you need |
Sentinel-Controlled |
Infinite with break |
In the body |
Runs infinite loop; breaks on special value |
Reading input until user says “quit” |
2.2.2.1. Condition-Controlled (Indefinite)#
In condition-controlled while loops, you have no idea how many times it will run; it depends on what happens during the loop.
The syntax of a standard while loop is:
while [condition]:
[statement(s)]
Here’s a concrete example: rolling a random number between 1 and 10 until we get a 7. The loop checks if num != 7 at the beginning of each iteration. As long as the rolled number is not 7, it prints the result and rolls again. When we finally roll a 7, the condition becomes false and the loop stops.
import random
num = 0
while num != 7: ### could be 1 try, could be 100
num = random.randint(1, 10)
print(f"Rolled: {num}")
Rolled: 9
Rolled: 8
Rolled: 7
2.2.2.2. Count-Controlled Loops (Definite)#
In count-controlled while loops, you control exactly how many times the loop will run before it starts.
The syntax for a counter-controlled loop:
[counter] = [initial value]
while [counter] [comparison] [limit]:
[statement(s)]
[counter] += [increment] # or -= for decrement
In the following example, the while loop runs as long as the variable count is less than 5. A while loop requires a counter to increment/decrement variable to be ready. In this example, we need to define an indexing variable, count.
count = 1 ### initialize the variable
while count < 5: ### condition to check
print(f'count is: {count}') ### format string to print count
count = count+1 ### increment count to avoid infinite loop
count is: 1
count is: 2
count is: 3
count is: 4
2.2.2.3. Sentinel-Controlled Loop#
A sentinel value is a special value that signals the end of input. A classic example is reading user input until “quit” is entered.
The syntax for a sentinel value loop:
while True:
[input/process data]
if [sentinel value detected]:
break
[process the data]
total = 0
while True:
value = input("Enter a number (or 'quit' to stop): ")
if value.lower() == 'quit':
break
total += int(value)
print(f"Sum of all numbers: {total}")
The result would be:
Sum of all numbers: 0
2.2.2.4. Infinite Loops#
An infinite loop is a while loop that never stops because its condition never becomes False. This happens when you forget to update the variable controlling the condition.
For example, this code would loop forever:
count = 1
while count < 5:
print(f'count is: {count}')
### Oops! We forgot to increment count — condition never changes!
Prevention: Always make sure your loop variable changes in a way that will eventually make the condition False.
2.2.3. for Loops#
A for loop repeats a block of code by iterating through a sequence, so it typically runs a known, fixed number of times without manual index bookkeeping.
Common kinds of for loops:
Loop through a sequence (
list,tuple,string).Loop using
range()to control the number of iterations.Loop with
enumerate()to get both index and value.Loop with
zip()to iterate over multiple sequences in parallel.Nested loops (loop within a loop).
Loop through files to process each line.
2.2.3.1. For Loop Syntax and Components#
Every for loop has key parts:
Header: The
forstatement line that defines the loop. It ends with a colon (:).Loop variable: The variable (e.g.,
item) that holds the current element in each iteration.Sequence: The collection being iterated (list, string, range, etc.).
Body: The indented block of code that runs each iteration.
Indentation: Python uses indentation to define the body—typically 4 spaces. Every line in the body must be indented the same amount.
for item in sequence:
# body: this block runs once per item
# print(). ### for example, a print statement to print n times
2.2.3.2. Loop through sequences#
The most common use of for loops is to iterate over a sequence (list, tuple, string, etc.) and process each element one at a time. The loop variable automatically takes on the value of each item as the loop executes.
Loop through a list with
forandin.Iterate over items in a sequence with a loop variable, one item at a time.
2.2.3.2.1. Lists#
Lists are one of the most common Python sequences. When you loop over a list, the loop variable takes on each element in order, letting you process each item one at a time.
### loop through an integer list
nums = [1, 2, 3, 4, 5]
for num in nums: ### n loops
print(num, end=" ") ### print n times of whatever
1 2 3 4 5
2.2.3.2.2. Tuples#
Tuples are also sequences that can be looped through just like lists. They behave the same way in loops, but tuples are immutable (cannot be changed after creation).
Two common patterns:
Simple iteration over a single tuple
Tuple unpacking when looping over a list of tuples
# Example tuple (single sequence)
colors = ("red", "green", "blue")
for color in colors:
print(color, end=" ") ### red green blue
print()
# Example list of tuples (for unpacking)
coordinates = [(1, 2), (3, 4), (5, 6)]
for x, y in coordinates:
print(f"({x}, {y})", end=" ") ### (1, 2) (3, 4) (5, 6)
red green blue
(1, 2) (3, 4) (5, 6)
### looping through a string list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit, end=" ") ### apple banana cherry
apple banana cherry
2.2.3.2.3. Dictionaries#
We can also loop through dictionaries. When looping through a dictionary:
Looping through the dictionary directly gives you the keys
To get values, use
.values()To get both keys and values, use
.items()
# Example dictionary
student = {"name": "Alice", "age": 20, "major": "Data Science"}
# Loop through keys (default)
for key in student:
print(key, end=" ") ### name age major
print()
# Loop through values
for value in student.values():
print(value, end=" ") ### Alice 20 Data Science
print()
# Loop through both keys and values
for key, value in student.items():
print(f"{key}: {value}", end=" | ") ### name: Alice | age: 20 | major: Data Science |
name age major
Alice 20 Data Science
name: Alice | age: 20 | major: Data Science |
2.2.3.2.4. Strings#
We can also loop through strings because strings are sequences as well. We can:
directly loop through a string, or
turn a string into a list for better manipulation.
s = 'abcde'
for char in s:
print(char, end=" ") ### a b c d e
print() ### print a newline
lyrics = 'we are all just prisoners here of our own device'
for word in lyrics:
print(word, end=" ")
a b c d e
w e a r e a l l j u s t p r i s o n e r s h e r e o f o u r o w n d e v i c e
To turn a string into a list of words, then loop through it:
Using
splitto make alistof wordsUse
forto loop through them.
lyrics = 'we are all just prisoners here of our own device'
print(lyrics) ### string
lyrics = lyrics.split() ### list
print(lyrics)
we are all just prisoners here of our own device
['we', 'are', 'all', 'just', 'prisoners', 'here', 'of', 'our', 'own', 'device']
Now we can loop through the word list and use a conditional statement to create programs. For example,
for word in lyrics:
if len(word) >= 5:
print(f"{word} is a long word!!")
prisoners is a long word!!
device is a long word!!
for word in lyrics:
if word == "device":
print("device found")
device found
2.2.3.3. Looping with range()#
The range() function generates a sequence of numbers that a for loop can step through one at a time.
The syntax of the range function is:
range(start, stop, step)
where the function parameters are:
start – where to begin (inclusive, default to 0)
stop – where to end (exclusive)
step – how much to increment each time
We can use a for loop that uses the range function to display a sequence of numbers. Observe the examples below for what the parameters do for us.
for i in range(10): ### start
print(i, end=' ')
0 1 2 3 4 5 6 7 8 9
for i in range(1, 5): ### start, stop
print(i, end=' ')
1 2 3 4
for i in range(1, 10, 2): ### start, stop, step
print(i, end=' ')
1 3 5 7 9
2.2.3.4. enumerate#
Sometimes you need both the position (index) and the value of items in a sequence. The enumerate() function gives you both: it pairs each element with its index, starting from 0 by default. This is useful when you need to:
Track which position you’re at in the loop
Use index-based logic conditionally (e.g., “do something special for the third item”)
Display results with numbering (e.g., “1. apple, 2. banana”)
Work with data where position matters (e.g., pandas columns with statistics)
for idx, fruit in enumerate(fruits, start=1):
print(idx, fruit, end=" ") ### 1 apple 2 banana 3 cherry
1 apple 2 banana 3 cherry
import pandas as pd
# Simple DataFrame
df = pd.DataFrame({
"age": [23, 25, 31, 19],
"height": [165, 170, 178, 160],
"weight": [60, 65, 80, 55]
})
# Use enumerate to see column order and summary stats
for idx, col in enumerate(df.columns, start=1):
mean_val = df[col].mean()
print(f"{idx}. {col}: mean = {mean_val:.1f}")
1. age: mean = 24.5
2. height: mean = 168.2
3. weight: mean = 65.0
2.2.3.5. Nested Loops#
A nested loop is a loop inside another loop. The inner loop runs fully for each iteration of the outer loop. Use nested loops for tasks like building grids, tables, or pairwise comparisons.
rows = ["A", "B", "C"]
cols = [1, 2, 3]
for r in rows:
for c in cols:
print(f"{r}{c}", end=" ")
print()
A1 A2 A3
B1 B2 B3
C1 C2 C3
Or, using the range function, to print out a multiplication table:
for i in range(2, 10):
print(f"{i}\t", end=" ")
for j in range(2, 10):
print(f"{i*j}\t", end=" ")
print()
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
2.2.3.6. Loop Control Statements#
You can control the execution of any loop (while or for) using the following statements:
break– Immediately exits the loop, even if the condition is stillTrue(forwhile) or there are more items (forfor).continue– Skips the remainder of the current iteration and returns to the top of the loop to check the condition (forwhile) or move to the next item (forfor).pass- Used to write empty loops (also used for empty control statements, functions, and classes).elseclause – Executes only if the loop finishes normally without abreak, and does not run if the loop is terminated by abreakstatement.
### break statement example
i = 1
while i < 6:
print(i, end=" ")
if i == 3:
break
i += 1
1 2 3
### continue statement example
i = 0
while i < 6:
i += 1
if i == 3:
continue
print(i, end=" ")
1 2 4 5 6
### pass statement example
a = 'geeksforgeeks'
i = 0
while i < len(a):
i += 1
pass
print('Value of i :', i)
Value of i : 13
pass works similarly as continue in while loop with distinctions:
Feature |
|
|
|---|---|---|
Definition |
A null operation; it literally does nothing. |
Skips the remainder of the current loop iteration. |
Context |
Can be used anywhere (loops, functions, classes, |
Only allowed inside loops ( |
Impact on Flow |
Execution continues to the next statement in the block. |
Execution jumps back to the start of the loop for the next cycle. |
Primary Use |
Syntactic placeholder (prevents “empty block” errors). |
Logic control (skips specific items based on a condition). |
Example Scenario |
Creating an empty function for future implementation. |
Printing only odd numbers by skipping even ones. |
### else clause with while loop (no break)
count = 1
while count < 4:
print(count, end=" ")
count += 1
else:
print("\nLoop finished normally!") # This runs because no break occurred
print()
### else clause with while loop (with break)
count = 1
while count < 10:
print(count, end=" ")
if count == 3:
break
count += 1
else:
print("\nLoop finished normally!") # This does NOT run because break terminated the loop
print("After the loop")
### else clause with for loop (no break)
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit, end=" ")
else:
print("\nAll fruits processed!") # This runs because no break occurred
1 2 3
Loop finished normally!
1 2 3 After the loop
apple banana cherry
All fruits processed!