Python's if and else Statements:
In Python, if and else statements are used for conditional execution. They allow your program to
make decisions and execute different blocks of code based on whether certain conditions are true or
false. This is a core concept in programming, enabling dynamic and responsive applications.
1. The if Statement :
The if statement is the simplest form of conditional control. It executes a block of code only if a
specified condition evaluates to True.
Syntax:
if condition:
# Code to execute if the condition is True
# (Indented block)
Key Points :
- The condition is a boolean expression (something that evaluates to True or False).
- The colon ( : ) after the condition is mandatory.
- The code block to be executed must be indented. Python uses indentation (whitespace) to define code
blocks, unlike other languages that use curly braces { }. Typically, 4 spaces are used for indentation.
Example :
#Example 1.1: Simple if statement
age = 20
if age >= 18:
print("You are eligible to vote.")
print("This line runs regardless of the condition.")
Explanation :
In this example, age >= 18 evaluates to True, so "You are eligible to vote." is printed.
The last print statement is outside the if block, so it always executes.
What if the condition is False?
# Example 1.2 : If condition is False
temperature = 25
if temperature > 30:
print("It's a hot day!")
print("Enjoy the weather!")
Explanation :
Here, temperature > 30 is False. Therefore, the indented print statement inside the if block is skipped.
"Enjoy the weather!" is still printed.
2. The if-else Statement :
The if-else statement provides an alternative path of execution when the if condition is False.
Syntax:
if condition:
# Code to execute if the condition is True
else:
# Code to execute if the condition is False
Key Points :
- The else block does not have a condition. It acts as a catch-all for when the if condition is False.
- Both the if and else blocks must be indented.
Example :
#Example 2.1: if-else statement
num = 7
if num % 2 == 0:
print(f"{num} is an even number.")
else:
print(f"{num} is an odd number.")
# Example 2.2: User input with if-else
user_input = input("Enter a number: ")
number = int(user_input) # Convert input to integer
if number > 0:
print("The number is positive.")
else:
print("The number is non-positive (zero or negative).")
Explanation :
In Example 2.1, 7 % 2 == 0 is False, so the else block executes. In Example 2.2,
the program takes user input, converts it to an integer, and then checks if it's positive or not.
3. The if-elif-else Ladder :
When you have multiple conditions to check, the if-elif-else (pronounced "if-else if-else") ladder is
used. elif is short for "else if".
Syntax:
if condition1:
# Code to execute if condition1 is True
elif condition2:
# Code to execute if condition1 is False AND condition2 is True
elif condition3:
# Code to execute if condition1 and condition2 are False AND condition3 is True
else:
# Code to execute if all preceding conditions (condition1, condition2, condition3, etc.) are False
Key Points :
- Python checks conditions sequentially from top to bottom.
- As soon as a condition evaluates to True, its corresponding block of code is executed,
and the rest of the elif and else statements in that ladder are skipped.
- You can have any number of elif blocks.
- The else block is optional. If omitted and none of the if or elif conditions are true, nothing in the conditional structure will execute.
Example :
# Example 3.1: Grade calculation
score = 85
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B")
elif score >= 70:
print("Grade: C")
elif score >= 60:
print("Grade: D")
else:
print("Grade: F")
# Example 3.2: Time-based greeting
import datetime
current_hour = datetime.datetime.now().hour
if current_hour < 12:
print("Good morning!")
elif 12 <= current_hour < 18:
print("Good afternoon!")
else:
print("Good evening!")
Explanation :
In Example 3.1, score >= 90 is False, but score >= 80 is True, so "Grade: B" is printed, and
the rest of the ladder is ignored. Example 3.2 dynamically greets the user based on the current hour.
4. Nested if-else Statements :
You can place if-else statements inside other if-else statements. This is called nesting.
It's useful when you need to check multiple layers of conditions.
Syntax :
if outer_condition:
# Code for outer_condition being True
if inner_condition1:
# Code for inner_condition1 being True
else:
# Code for inner_condition1 being False
else:
# Code for outer_condition being False
if another_inner_condition:
# Code for another_inner_condition being True
else:
# Code for another_inner_condition being False
Key Points :
- Indentation is crucial for nested statements to maintain clarity and correct execution flow.
- Too many levels of nesting can make code hard to read and maintain. Consider refactoring complex
nested if statements if they become too deep.
Example :
# Example 4.1: Movie ticket pricing with nested if-else
age = 15
is_student = True
if age < 18:
if is_student:
print("Student discount: Ticket price is $5.")
else:
print("Child price: Ticket price is $8.")
else:
# Age is 18 or above
if age >= 60:
print("Senior discount: Ticket price is $7.")
else:
print("Adult price: Ticket price is $12.")
Explanation :
Here, the outer if checks the age. If age < 18 is true, then an inner if checks is_student.
If age >= 18 is true (the else block of the outer if), then another inner if checks for senior discount.
5. Logical Operators (and, or, not) :
You can combine multiple conditions using logical operators to create more complex conditional expressions.
- and: Returns True if both conditions are True.
- or: Returns True if at least one condition is True.
- not: Reverses the boolean value of a condition (e.g., not True is False).
Example :
# Example 5.1: Using 'and'
temperature = 28
is_sunny = True
if temperature > 25 and is_sunny:
print("Great day for an outdoor activity!")
else:
print("Might be better to stay indoors or find another activity.")
# Example 5.2: Using 'or'
has_ticket = False
has_invitation = True
if has_ticket or has_invitation:
print("Welcome to the event!")
else:
print("Sorry, you need a ticket or an invitation to enter.")
# Example 5.3: Using 'not'
is_logged_in = False
if not is_logged_in:
print("Please log in to access this feature.")
else:
print("Welcome, user!")
# Example 5.4: Combining logical operators
age = 22
has_drivers_license = True
has_car = False
if (age >= 18 and has_drivers_license) and not has_car:
print("You can drive, but you need a car!")
elif (age >= 18 and has_drivers_license) and has_car:
print("You're all set to drive!")
else:
print("You cannot drive yet or don't have a license.")
6. Ternary Operator (Conditional Expressions - Advanced Basic):
For simple if-else assignments, Python offers a concise one-line syntax called the ternary
operator or conditional expression.
Syntax:
value_if_true if condition else value_if_false
Key Points :
- This is an expression, meaning it evaluates to a value, which can then be assigned to a variable or used directly.
- It's ideal for simple assignments, not for executing complex blocks of code.
Example :
# Example 6.1: Simple even/odd check
number = 10
status = "Even" if number % 2 == 0 else "Odd"
print(f"The number {number} is {status}.")
# Example 6.2: Assigning a message
is_open = True
message = "Store is open!" if is_open else "Store is closed."
print(message)
# Example 6.3: Using directly in print
score = 75
print("Passed" if score >= 60 else "Failed")
7. Chained Comparisons (Advanced) :
Python allows you to chain comparison operators, which can make your conditions more readable,
especially when checking if a value falls within a range.
Syntax:
lower_bound <= value <= upper_bound
This is equivalent to lower_bound <= value and value <= upper_bound.
Example :
# Example 7.1: Checking if a number is within a range
num = 15
if 10 <= num <= 20:
print(f"{num} is between 10 and 20 (inclusive).")
else:
print(f"{num} is outside the range 10-20.")
# Example 7.2: Grade check with chained comparison
score = 88
if 90 <= score <= 100:
print("Excellent (A)")
elif 80 <= score < 90: # Note: 'score < 90' is naturally handled by elif order, but explicit range is clearer
print("Very Good (B)")
else:
print("Needs Improvement")
8. if with in and not in Operators (Advanced) :
These operators are useful for checking membership in sequences (strings, lists, tuples, sets,
dictionaries).
Syntax:
element in sequence
element not in sequence
Example :
# Example 8.1: Checking if an item is in a list
fruits = ["apple", "banana", "cherry"]
favorite_fruit = "banana"
if favorite_fruit in fruits:
print(f"Yes, {favorite_fruit} is in the list.")
else:
print(f"No, {favorite_fruit} is not in the list.")
# Example 8.2: Checking if a character is in a string
text = "Hello World"
if "o" in text:
print("The letter 'o' is in the text.")
# Example 8.3: Checking if an item is NOT in a list
disallowed_words = ["badword1", "badword2"]
user_comment = "This is a good comment."
if user_comment not in disallowed_words:
print("Comment approved.")
else:
print("Comment contains disallowed words.")
9. Truthiness and Falsiness (Deep Dive) :
In Python, many values are inherently considered "truthy" or "falsy" when evaluated in a boolean context
(like an if condition), even if they are not explicitly True or False.
Falsy Values :
- None
- False
- Numeric zero of all types: 0, 0.0, 0j (complex zero)
- ' ' (empty string)
- [ ] (empty list)
- { } (empty dictionary)
- ( ) (empty tuple)
Truthy Values :
- Any non-empty sequence or mapping (e.g., [1, 2], 'hello', {1: 'a'})
- Any non-zero number (e.g., 1, -5, 3.14)
- True
- Objects (by default, they are truthy unless their __bool__() or __len__() methods are defined to
return False or zero, respectively).
Example :
element in sequence
element not in sequence
Example :
# Example 9.1: Truthiness of numbers
if 0:
print("This will not print (0 is falsy)")
if 1:
print("This will print (1 is truthy)")
if -5:
print("This will print (-5 is truthy)")
# Example 9.2: Falsiness of empty sequences
my_list = []
if my_list:
print("List is not empty.")
else:
print("List is empty (falsy).")
my_string = "Hello"
if my_string:
print("String is not empty.")
else:
print("String is empty (falsy).")
# Example 9.3: Falsiness of None
value = None
if value:
print("Value is not None.")
else:
print("Value is None (falsy).")
10. if with try-except (Advanced Error Handling with Conditionals) :
Often, you'll need to check for conditions that might raise errors (exceptions).
try-except blocks are used for this, and if statements can be used within them to handle
different scenarios after an exception.
Example:
# Example 10.1: Handling invalid input
try:
user_input = input("Enter a number: ")
number = int(user_input)
if number % 2 == 0:
print(f"{number} is an even number.")
else:
print(f"{number} is an odd number.")
except ValueError:
print("Invalid input! Please enter a valid integer.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
Explanation :
The try block attempts to convert user_input to an integer. If the input is not a valid integer
(e.g., "hello"), a ValueError is raised, and the except ValueError block is executed. If the conversion
is successful, the if-else statement proceeds normally.
11. if with Functions (High Level) :
Conditions are often used within functions to control their behavior and return different
results based on inputs.
Example:
# Example 11.1: Function returning different values
def get_discounted_price(original_price, customer_type):
if customer_type == "premium":
return original_price * 0.8 # 20% discount
elif customer_type == "student":
return original_price * 0.9 # 10% discount
else:
return original_price # No discount
price1 = get_discounted_price(100, "premium")
print(f"Premium price: ${price1}")
price2 = get_discounted_price(100, "regular")
print(f"Regular price: ${price2}")
# Example 11.2: Function with validation
def divide_numbers(a, b):
if b == 0:
print("Error: Cannot divide by zero!")
return None # Return None to indicate failure
else:
return a / b
result1 = divide_numbers(10, 2)
if result1 is not None:
print(f"Result of division: {result1}")
result2 = divide_numbers(5, 0)
if result2 is None: # Check if the function returned None
print("Division failed as expected.")
12. if with List Comprehensions and Generator Expressions (Advanced/Concise) :
if can be embedded within list comprehensions and generator expressions to filter elements or apply conditional transformations.
Syntax (Filtering) :
[expression for item in iterable if condition]
Syntax (Conditional Expression within Comprehension) :
[value_if_true if condition else value_if_false for item in iterable]
Example :
# Example 12.1: Filtering even numbers from a list
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = [num for num in numbers if num % 2 == 0]
print(f"Even numbers: {even_numbers}") # Output: [2, 4, 6, 8, 10]
# Example 12.2: Applying conditional transformation
transformed_numbers = [num * 2 if num % 2 == 0 else num for num in numbers]
print(f"Transformed numbers: {transformed_numbers}") # Output: [1, 4, 3, 8, 5, 12, 7, 16, 9, 20]
# Example 12.3: Generator expression (similar to list comprehension but lazy evaluation)
squared_odds = (num**2 for num in numbers if num % 2 != 0)
print("Squared odd numbers (generator):")
for sq in squared_odds:
print(sq)
13. Short-Circuit Evaluation (Deep Dive) :
Python's logical operators (and, or) use short-circuit evaluation. This means that they evaluate
conditions only as much as necessary to determine the overall result.
- and: If the first condition is False, the entire expression is False, and the second condition
is not evaluated.
- or: If the first condition is True, the entire expression is True, and the second condition is not evaluated.
This can be useful for performance optimization and preventing errors.
Example:
# Example 13.1: Short-circuiting with 'and' to prevent ZeroDivisionError
def check_and_divide(numerator, denominator):
# If denominator is 0, the first part is False, and (numerator / denominator) is never evaluated
if denominator != 0 and (numerator / denominator) > 5:
print("Division result is greater than 5.")
else:
print("Cannot divide by zero or result is not greater than 5.")
check_and_divide(10, 2)
check_and_divide(10, 0) # No ZeroDivisionError
check_and_divide(10, 3) # 3.33 is not > 5
# Example 13.2: Short-circuiting with 'or'
def is_valid_input(value):
print(f"Checking value: {value}")
return value is not None and value != ""
# If is_valid_input("hello") is True, is_valid_input("world") is NOT called.
if is_valid_input("hello") or is_valid_input("world"):
print("At least one input is valid.")
14. match-case Statement (Python 3.10+) - Structured Pattern Matching :
While not strictly if-else, Python 3.10 introduced the match-case statement, which is a powerful way
to handle multiple conditions in a more structured way, especially when dealing with different data
patterns. It's an alternative to long if-elif-else chains for certain scenarios.
Syntax :
match subject:
case pattern1:
# Code if subject matches pattern1
case pattern2:
# Code if subject matches pattern2
case _: # The "wildcard" or default case (like else)
# Code if no other pattern matches
Example :
# Example 14.1: Basic match-case
command = "start"
match command:
case "start":
print("Starting the system...")
case "stop":
print("Stopping the system...")
case "restart":
print("Restarting the system...")
case _: # Default case
print("Unknown command.")
# Example 14.2: Match-case with multiple values or patterns
status_code = 403
match status_code:
case 200:
print("OK")
case 400 | 401 | 403: # Multiple patterns for the same action
print("Client error (Bad Request, Unauthorized, or Forbidden)")
case 500:
print("Server error")
case _:
print("Other status code")
# Example 14.3: Match-case with if-guard (conditional matching)
point = (10, -5) # A tuple representing (x, y) coordinates
match point:
case (x, y) if x > 0 and y > 0:
print(f"Point ({x},{y}) is in the first quadrant.")
case (x, y) if x < 0 and y > 0:
print(f"Point ({x},{y}) is in the second quadrant.")
case (x, y) if x < 0 and y < 0:
print(f"Point ({x},{y}) is in the third quadrant.")
case (x, y) if x > 0 and y < 0:
print(f"Point ({x},{y}) is in the fourth quadrant.")
case (0, y) if y != 0:
print(f"Point ({y}) is on the Y-axis.")
case (x, 0) if x != 0:
print(f"Point ({x}) is on the X-axis.")
case (0, 0):
print("Point is at the origin.")
case _:
print("Not a 2D point or unhandled case.")
Note on match-case: While it uses patterns and conditions (if guards), it's a distinct control flow
statement from the if-elif-else ladder. It excels in pattern matching against various data structures,
not just simple boolean conditions.
Best Practices and Common Pitfalls :
- Indentation is paramount: Incorrect indentation will lead to IndentationError or logical errors.
- Clarity over brevity: While ternary operators are concise, don't overuse them if the logic becomes hard to read.
- Order matters in if-elif-else: Conditions are checked sequentially. Place more specific conditions before more general ones.
# Bad example (will never reach the second elif if score >= 70)
score = 85
if score >= 70:
print("C")
elif score >= 80: # This will never be reached if score is 85, as the first condition already matched
print("B")
# Good example
if score >= 80:
print("B")
elif score >= 70:
print("C")
- Avoid excessive nesting: If you have many nested if statements, consider refactoring your code using
functions, logical operators, or even the match-case statement for better readability.
- Use meaningful variable names: This helps in understanding the conditions.
- Consider using dictionaries for mapping: If you have many elif conditions that map inputs to
outputs, a dictionary lookup might be more efficient and readable.
# Instead of:
color = "red"
if color == "red":
code = "#FF0000"
elif color == "blue":
code = "#0000FF"
# ...
# Use a dictionary:
color_codes = {"red": "#FF0000", "blue": "#0000FF", "green": "#00FF00"}
color = "red"
code = color_codes.get(color, "Unknown") # .get() allows a default if key not found
print(code)