top of page

Beginner: Chapter 2 - Python Control Flow: Mastering If Statements, Loops, and Functions | The GPM


Control flow determines the order in which your Python code executes, enabling decision-making, repetition, and modular programming. This comprehensive guide covers if statements for conditional logic, loops (for and while) for iteration, and functions for reusable code blocks.

Conditional Statements: If, Elif, Else

If statements execute code based on boolean conditions using dynamic evaluation. Basic structure: if condition: block executes when True. Indentation defines the block scope.

Basic if statement:if age >= 18:print("Adult access granted")else:print("Restricted access")

Multiple conditions chain with elif:if score >= 90:print("Grade: A")elif score >= 80:print("Grade: B")elif score >= 70:print("Grade: C")else:print("Needs improvement")

Conditions use comparison operators (==, !=, >, <, >=, <=) and logical operators (and, or, not). Short-circuit evaluation: and stops at first False, or stops at first True.

Nested ifs handle complex logic:if is_member:if purchase_total > 100:discount = 0.15else:discount = 0.10else:discount = 0.00

Truthy/falsy values simplify conditions: empty strings/lists/dicts, 0, None, False are falsy; non-empty containers, non-zero numbers, non-None are truthy.if user_name: # True if non-empty stringprint(f"Welcome, {user_name}")if shopping_cart: # True if non-empty listtotal = sum(item.price for item in shopping_cart)

Ternary operator (conditional expression) for one-liners:status = "approved" if credit_score > 700 else "pending"message = "Valid" if email.endswith("@gmail.com") else "Invalid domain"

While Loops: Condition-Based Iteration

While loops repeat while a condition remains True, ideal for unknown iteration counts.counter = 0while counter < 5:print(f"Count: {counter}")counter += 1

Infinite loops need break:user_input = ""while user_input != "quit":user_input = input("Enter command: ")if user_input == "help":print("Available: status, reset, quit")

Else clause runs if no break occurred:attempts = 0while attempts < 3:pin = input("Enter PIN: ")if verify_pin(pin):print("Access granted")breakattempts += 1else:print("Account locked")

Common pattern: input validation:valid = Falsewhile not valid:try:age = int(input("Enter age: "))if 0 <= age <= 120:valid = Trueelse:print("Age must be 0-120")except ValueError:print("Enter numeric age")

For Loops: Sequence Iteration

For loops iterate over sequences (lists, strings, ranges, dicts), cleaner than while for known iterations.Iterate lists:fruits = ["apple", "banana", "cherry"]for fruit in fruits:print(f"I like {fruit}")

Range function generates sequences:for i in range(5): # 0 to 4print(i)

for i in range(2, 8): # 2 to 7print(i)

for i in range(0, 10, 2): # 0,2,4,6,8print(i)

Enumerate for index-value pairs:colors = ["red", "green", "blue"]for index, color in enumerate(colors):print(f"{index}: {color}")

Dictionary iteration:student_grades = {"Alice": 95, "Bob": 87, "Charlie": 92}for name, grade in student_grades.items():print(f"{name}: {grade}")

Loop controls:

  • break exits immediately

  • continue skips to next iteration

  • else runs if no break

Password guesser example:password = "secret123"attempts = 0for attempt in ["pass123", "secret", "secret123", "hackme"]:attempts += 1if attempt == password:print(f"Cracked in {attempts} tries!")breakprint(f"Try {attempts}: {attempt}")else:print("Password not found")

List Comprehensions: Elegant Iteration

List comprehensions create lists concisely:squares = [x**2 for x in range(10)]evens = [x for x in range(20) if x % 2 == 0]lengths = [len(word) for word in ["python", "java", "rust"]]

Nested comprehensions:matrix = [,, ]​flattened = [num for row in matrix for num in row]

Dictionary/set comprehensions:squares_dict = {x: x**2 for x in range(5)}unique_lengths = {len(word) for word in ["book", "chair", "bookcase"]}

Functions: Reusable Code Blocks

Functions encapsulate logic using def keyword. Basic structure:def greet(name):return f"Hello, {name}!"

Define with parameters:def calculate_area(length, width):return length * width

Call: result = calculate_area(10, 5)

Default parameters:def book_room(name, room_type="standard", nights=1):cost_per_night = 100 if room_type == "suite" else 75return name, cost_per_night * nights

book_room("Alice") # Uses defaultsbook_room("Bob", "suite", 3)

Keyword arguments (order-independent):def create_profile(name, age, city="Unknown"):return f"{name}, {age}, {city}"

create_profile(age=25, name="Charlie")

Variable arguments:def sum_all(*numbers):return sum(numbers)

sum_all(1, 2, 3, 4) # 10

Keyword variable arguments:def save_user(**user_data):print(f"Saving: {user_data}")

save_user(name="Dana", age=30, city="NYC")

Lambda functions (anonymous):square = lambda x: x2double = lambda x, y: x * ynumbers =​squared = list(map(lambda x: x2, numbers))

Scope and Lifetime

LEGB rule: Local, Enclosing, Global, Built-in.x = "global"def outer():x = "enclosing"def inner():x = "local"print(x)inner()print(x)

outer()print(x)

Nonlocal keyword modifies enclosing scope:x = "global"def outer():x = "enclosing"def inner():nonlocal xx = "modified enclosing"inner()print(x)

Global modifies module scope:count = 0def increment():global countcount += 1

Practical Examples and Patterns

Factorial recursive function:def factorial(n):if n <= 1:return 1return n * factorial(n-1)

Fibonacci iterative:def fibonacci(n):if n <= 1:return na, b = 0, 1for _ in range(2, n + 1):a, b = b, a + breturn b

Data validation function:def validate_email(email):if "@" not in email or "." not in email:return Falselocal, domain = email.split("@")if local and domain.split("."):return Truereturn False

Batch processing:def process_files(file_list):results = []for filename in file_list:try:with open(filename, 'r') as f:content = f.read()results.append(len(content))except FileNotFoundError:results.append(0)return results

Error Handling in Control Flow

Combine try/except with control structures:def safe_divide(a, b):try:if b == 0:raise ZeroDivisionError("Cannot divide by zero")return a / bexcept (ZeroDivisionError, TypeError) as e:print(f"Error: {e}")return None

Loop with timeout:import timedef wait_for_condition(timeout=10):start = time.time()while time.time() - start < timeout:if check_condition():return Truetime.sleep(0.1)return False

Best Practices Summary Table

Control Structure

Best Use Case

Common Pitfall

if/elif/else

Decision trees

Deep nesting (>3 levels)

while

Unknown iterations

Infinite loops

for/range

Known sequences

Modifying list while iterating

functions

Reusability

Mutable default arguments

comprehensions

List transformations

Overly complex logic

Complete Working Examples

User authentication system:def authenticate_user(username, password):valid_users = {"admin": "secret123","user1": "pass456","guest": ""}if username in valid_users and valid_users[username] == password:return f"Welcome, {username}!"else:return "Invalid credentials"

Shopping cart calculator:def calculate_cart(cart_items):total = 0for item in cart_items:if item['quantity'] > 0:subtotal = item['price'] item['quantity']if subtotal > 100:subtotal = 0.9 # 10% discounttotal += subtotalreturn round(total, 2)

Prime number generator:def primes_up_to(n):if n < 2:return []sieve = [True] (n + 1)sieve = sieve = False​for i in range(2, int(n*0.5) + 1):if sieve[i]:sieve[ii::i] = [False] * ((n - ii) // i + 1)return [i for i in range(n + 1) if sieve[i]]

This control flow foundation enables complex programs. Practice by building calculators, games, and data processors.


Disclosure:

  • As an Amazon Associate I earn from qualifying purchases.

  • We may earn a commission when you buy through links on our site, at no extra cost to you.


Check out some great offers below: 



Comments


Subscribe to Our Newsletter

  • Image by Mariia Shalabaieva
  • Instagram
  • Facebook

© 2025 - Powered and secured by TheGPM. All rights reserved.

bottom of page