Control Flow in Python: Conditions, Loops, and Logic

Conditional Statements (if / elif / else)

The if statement is your program’s decision-maker. It executes code only if a condition is True.

Basic structure:

Python

age = 18

if age >= 18:
    print("You can vote!")
else:
    print("Too young to vote.")

Add branches with elif (else if):

Python

score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
else:
    grade = "F"

print(f"Your grade: {grade}")

Key points:

  • Conditions must evaluate to bool (or truthy/falsy—we covered this last time).
  • Indentation defines the block.
  • No parentheses required, but you can use them for clarity: if (age >= 18 and score > 80):.

Nested ifs are possible but can get messy—we’ll address that later.

Full example: A simple login simulator.

Python

username = input("Username: ")
password = input("Password: ")

if username == "admin":
    if password == "secret":
        print("Access granted!")
    else:
        print("Wrong password.")
else:
    print("Unknown user.")

Run this interactively. Juniors: Always consider edge cases—like empty inputs.

Boolean Logic and Comparison Operators

Conditions rely on operators.

Comparison: == (equal), != (not equal), <, >, <=, >=.

Chaining: a < b <= c (like math).

Logical: and, or, not.

Python

temperature = 25
is_sunny = True

if 20 <= temperature <= 30 and is_sunny:
    print("Perfect weather!")
elif temperature < 10 or not is_sunny:
    print("Stay indoors.")

Operator precedence: Comparisons before not, then and, then or. Use parentheses to clarify.

Membership and identity:

  • in / not in: Check if item in sequence.
  • is / is not: Identity check (same object—remember None and singletons).

Python

fruits = ["apple", "banana"]

if "apple" in fruits:
    print("Healthy choice!")

value = None
if value is None:
    print("No value set.")

Full example: Validating user input.

Python

email = input("Enter email: ")

if "@" in email and "." in email:
    if email.endswith(".com") or email.endswith(".org"):
        print("Valid email.")
    else:
        print("Unsupported domain.")
else:
    print("Invalid format.")

Middle devs: For complex logic, consider truth tables or refactor into functions.

for Loops vs while Loops

Loops repeat code. Choose based on need.

for loops: Ideal for iterating over sequences (lists, strings, ranges).

Python

for i in range(5):  # 0 to 4
    print(i)

# Over list
names = ["Alice", "Bob", "Charlie"]
for name in names:
    print(f"Hello, {name}")

while loops: Run until condition False. Great for unknown iterations.

Python

count = 0
while count < 5:
    print(count)
    count += 1

Infinite loops: while True:—break out with conditions.

Comparison:

  • Use for when you know the sequence or count.
  • Use while for condition-based (e.g., waiting for input).

Full example: Guessing game.

Python

import random

secret = random.randint(1, 10)
guess = 0

while guess != secret:
    guess = int(input("Guess a number 1-10: "))
    if guess < secret:
        print("Too low!")
    elif guess > secret:
        print("Too high!")
    else:
        print("Correct!")

print("Game over.")

This uses while naturally since guesses vary.

break, continue, and pass – When to Use Them

Control loop flow precisely.

  • break: Exit loop immediately.
  • continue: Skip to next iteration.
  • pass: Do nothing (placeholder).

Python

for num in range(10):
    if num == 5:
        continue  # Skip 5
    if num > 8:
        break  # Stop at 9+
    print(num)
# Prints 0-4, 6-8

pass example:

Python

for i in range(5):
    if i % 2 == 0:
        pass  # TODO: handle even
    else:
        print("Odd:", i)

Full example: Prime search with break.

Python

def find_prime(start=2):
    num = start
    while True:
        is_prime = True
        for i in range(2, int(num**0.5) + 1):
            if num % i == 0:
                is_prime = False
                break  # No need to check further
        if is_prime:
            return num
        num += 1

print("Next prime after 10:", find_prime(11))

Juniors: Use sparingly—overuse leads to spaghetti code.

Looping Patterns Every Developer Should Know

Common idioms:

  • Enumerate: Index + item.

Python

fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}: {fruit}")
  • Zip: Parallel iteration.

Python

names = ["Alice", "Bob"]
scores = [95, 88]
for name, score in zip(names, scores):
    print(f"{name}: {score}")
  • List comprehensions: Concise loops.

Python

squares = [x**2 for x in range(10) if x % 2 == 0]
print(squares)  # [0, 4, 16, 36, 64]
  • Dictionary comprehensions.

Python

word_lengths = {word: len(word) for word in ["python", "is", "fun"]}
print(word_lengths)

Full example: Processing data.

Python

transactions = [("deposit", 100), ("withdraw", 50), ("deposit", 200)]
balance = 0

for action, amount in transactions:
    if action == "deposit":
        balance += amount
    elif action == "withdraw":
        balance -= amount

print("Final balance:", balance)

Middle devs: Comprehensions are Pythonic but don’t nest deeply—readability first.

Avoiding Deep Nesting and Spaghetti Code

Deep nesting (if inside loop inside if) hurts readability.

Solutions:

  • Early returns/continues.
  • Guard clauses.
  • Refactor to functions.

Bad:

Python

if condition1:
    if condition2:
        for item in items:
            if item.valid:
                # do work

Better:

Python

if not condition1 or not condition2:
    return  # or continue

for item in items:
    if not item.valid:
        continue
    # do work

Use any() / all() for conditions.

Python

numbers = [1, 2, 3, 4]
if all(n >for n in numbers):
    print("All positive")

Flatten with comprehensions or loops.

Full example: Refactored validator.

Python

def validate_user(user):
    if not user.get("name"):
        return "Missing name"
    if not user.get("email") or "@" not in user["email"]:
        return "Invalid email"
    if user["age"] < 18:
        return "Too young"
    return "Valid"

user = {"name": "Bob", "email": "bob@example.com", "age": 20}
print(validate_user(user))

Early returns keep main logic flat.

Performance Considerations in Loops

Loops can be bottlenecks.

Tips:

  • List comprehensions often faster than for-loops with append.
  • Avoid work inside loops (e.g., repeated calculations).
  • Use built-ins: sum(), max(), etc.

Example timing (results vary, but comprehensions win):

Python

import timeit

nums = list(range(10000))

# Comprehension
time_comp = timeit.timeit('[x*2 for x in nums]', globals=globals(), number=1000)

# For loop
time_loop = timeit.timeit('result = []\nfor x in nums:\n    result.append(x*2)', globals=globals(), number=1000)

print(f"Comprehension: {time_comp:.4f}s")
print(f"For loop: {time_loop:.4f}s")

Use generators for memory: (x*2 for x in nums).

For heavy loops, consider numba or profiling with cProfile.

Python

import cProfile

def slow_function():
    total = 0
    for i in range(1000000):
        total += i ** 2
    return total

cProfile.run('slow_function()')

Identify hotspots and optimize.

Real-World Examples and Exercises

Tie it together: Build a CLI todo list.

Python

todos = []

while True:
    print("\n1. Add  2. List  3. Complete  4. Quit")
    choice = input("Choose: ")

    if choice == "1":
        task = input("Task: ")
        todos.append({"task": task, "done": False})
    elif choice == "2":
        for i, todo in enumerate(todos, 1):
            status = "Done" if todo["done"] else "Pending"
            print(f"{i}. {todo['task']} [{status}]")
    elif choice == "3":
        idx = int(input("Task number: ")) - 1
        if 0 <= idx < len(todos):
            todos[idx]["done"] = True
    elif choice == "4":
        break
    else:
        print("Invalid")

Run this—it’s a full app using everything here.

Leave a Reply

Your email address will not be published. Required fields are marked *