No history yet

Advanced Logic and Control Flow

Branching Beyond If-Else

You already know how to use if and else to make a program choose between two paths. But what happens when you have more than two possibilities? You could write a series of if statements, but that can be inefficient. The program would have to check every single if condition, even after it's already found one that's true.

Python gives us a cleaner, more efficient way to handle this: the if-elif-else chain. The elif keyword is short for "else if." It lets you check multiple conditions in order. As soon as one condition is met, its code block runs, and the rest of the chain is skipped entirely.

# Get user's age
age = int(input("Enter your age: "))

if age < 13:
    print("You're a child.")
elif age < 18:
    print("You're a teenager.")
elif age < 65:
    print("You're an adult.")
else:
    print("You're a senior.")

# Try entering 15. The program will print "You're a teenager."
# and immediately skip the last two checks.

An if-elif-else chain is a single structure. It can have as many elif blocks as you need, but only one if (at the start) and at most one else (at the end).

Truthiness and Falsiness

In Python, conditional statements don't just work with the literal values True and False. Any value can be evaluated in a boolean context. This concept is often called "truthiness."

Some values are considered "falsy," meaning they evaluate to False. These include the number 0, the special value None, and any empty collection, like an empty string "", an empty list [], or an empty dictionary {}. Everything else is considered "truthy."

This allows for a more concise and readable style of coding, often referred to as "Pythonic." Instead of checking the length of a list, you can just check the list itself.

Falsy (Evaluates to False)Truthy (Evaluates to True)
FalseTrue
NoneAny non-zero number (e.g., 1, -10)
0, 0.0Any non-empty string (e.g., "hello")
"", '' (empty strings)Any non-empty list (e.g., [1, 2])
[], (), {} (empty collections)Any non-empty dictionary (e.g., {"key": "value"})
my_list = []

# The long way
if len(my_list) > 0:
    print("List has items.")
else:
    print("List is empty.")

# The Pythonic way, using truthiness
if my_list: # This evaluates to False because the list is empty
    print("List has items.")
else:
    print("List is empty.")

Combining Conditions

Sometimes a single check isn't enough. You might need to verify that multiple conditions are true, or that at least one of several conditions is true. Python provides three logical operators for this: and, or, and not.

  • and: Evaluates to True only if both conditions on either side of it are true.
  • or: Evaluates to True if at least one of the conditions is true.
  • not: Inverts the boolean value of a condition. not True becomes False.

These operators use a technique called to be more efficient. For an and statement, if the first condition is false, Python knows the whole expression must be false and doesn't bother checking the second one. Similarly, for an or statement, if the first condition is true, the whole thing must be true, so the second condition is skipped.

# Example: Validating a password
password = "p@ssword123"

# Must be longer than 8 chars AND contain a number
if len(password) > 8 and any(char.isdigit() for char in password):
    print("Password is valid.")
else:
    print("Password must be longer than 8 characters and contain a number.")

Another powerful tool for checking conditions are the membership operators: in and not in. These check for the presence of a value within a sequence, like a string, list, or tuple. It's a much cleaner way to see if something exists in a collection than writing a loop yourself.

allowed_users = ["alice", "bob", "charlie"]
current_user = "dave"

if current_user in allowed_users:
    print("Access granted.")
else:
    print("Access denied.")

# You can also check for substrings
if 'fruit' in 'this is a fruitful discussion':
    print("Found it!")

Nested Conditions

You can place control flow statements inside one another. This is called nesting. For example, you could have an if statement inside another if statement. This is useful when you need to perform a second check only if the first one passes.

However, be careful with nesting. If you nest too deeply, your code can become very difficult to read and understand. Each level of indentation adds a layer of complexity. Often, a deeply nested structure can be simplified by using logical operators like and or by reorganizing the logic. A core principle of good Python code is to keep it as flat as possible, a concept from which states, "Flat is better than nested."

# Nested approach
age = 25
has_license = True

if age >= 18:
    if has_license:
        print("You are eligible to drive.")
    else:
        print("You are old enough, but you need a license.")
else:
    print("You are not old enough to drive.")

# Flatter approach using 'and'
if age >= 18 and has_license:
    print("You are eligible to drive.")
elif age >= 18 and not has_license:
    print("You are old enough, but you need a license.")
else: # age < 18
    print("You are not old enough to drive.")

Mastering these control flow techniques allows you to write programs that can handle complex logic and make nuanced decisions, moving beyond simple scripts to more powerful applications.

Quiz Questions 1/6

What is the primary advantage of using an if-elif-else chain over a series of separate if statements?

Quiz Questions 2/6

What will the following Python code print?

score = 75
if score >= 90:
    print('A')
elif score >= 80:
    print('B')
elif score >= 70:
    print('C')
else:
    print('F')