Nested Conditionals & Logical Operators
2077 words
10 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Nested Conditionals & Logical Operators > **Why read this?** Real-world decisions are rarely simple yes/no. Eligibility for a loan might depend on age, income, credit score, AND employment status — all interacting.

Nested Conditionals & Logical Operators
Why read this? Real-world decisions are rarely simple yes/no. Eligibility for a loan might depend on age, income, credit score, AND employment status — all interacting. Nested conditionals and logical operators let you model complex decision logic cleanly.
🎯 Learning Objectives
By the end of this topic, you will be able to:
- Nest
ifstatements inside each other for multi-level decisions - Simplify complex conditions with
and,or,not - Use short-circuit evaluation to write safer conditions
- Understand the difference between
elifchains and nestedif - Write readable conditionals that avoid deep nesting
📋 Prerequisites
- Conditionals — if/elif/else — Basic if/elif/else knowledge required.
- Operators & Expressions — Logical operators.
📖 Core Content
7.1 What Problem Do Nested Conditionals Solve?
Intuition: Sometimes a decision depends on a previous decision. "If you're a student, then check if you have a valid ID. If you have a valid ID, apply student discount." The second check only makes sense after the first passes. Nesting handles this naturally.
7.2 Nested if — If Inside If
python# runnable age = 25 has_id = True if age >= 18: print("Age verified.") if has_id: print("ID verified. Entry granted.") else: print("ID required for entry.") else: print("Too young for entry.")
Output:
pseudoAge verified. ID verified. Entry granted.
Flow:
Diagram
Rendering diagram
7.3 Nested vs. elif — When to Use Which
Use nested if when conditions are hierarchical (B depends on A). Use elif when conditions are alternatives (A OR B OR C).
python# runnable # Scenario 1: elif (alternatives) - grade classification score = 85 if score >= 90: print("A") # Only ONE can be true elif score >= 80: print("B") elif score >= 70: print("C") else: print("D or F") # Scenario 2: nested (hierarchical) - loan decision income = 60000 has_collateral = True credit_score = 720 if income > 30000: print("Income requirement met.") if credit_score >= 700: print("Good credit.") if has_collateral: print("Loan approved!") else: print("Collateral required.") else: print("Credit score too low.") else: print("Income too low.")
7.4 Simplifying with Logical Operators
Often you can replace nesting with
and:python# runnable age = 25 has_ticket = True is_vip = False # Deeply nested (hard to read) if age >= 18: if has_ticket or is_vip: print("Welcome to the event!") # Simplified with logical operators (easier to read) if age >= 18 and (has_ticket or is_vip): print("Welcome to the event!")
Rule of thumb: If you have more than 3 levels of nesting, refactor with
and/or or use functions.7.5 Short-Circuit Evaluation in Depth
python# runnable def check_a(): print("check_a called") return False def check_b(): print("check_b called") return True # With 'and': if first is False, second is NEVER evaluated print("Testing 'and' with False first:") result = check_a() and check_b() # check_b NEVER runs! print(f"Result: {result}") print("\nTesting 'and' with True first:") result = check_b() and check_a() # both run print(f"Result: {result}")
Output:
pseudoTesting 'and' with False first: check_a called Result: False Testing 'and' with True first: check_b called check_a called Result: False
Practical applications:
python# Safe division: if x is 0, the division never happens if x != 0 and 10 / x > 2: print("Condition met") # Safe access: if list is non-empty, check first element if my_list and my_list[0] == target: print("Found!")
7.6 Combining not with in
python# runnable user_role = "guest" if user_role not in ("admin", "moderator"): print("Access denied. You need moderator privileges.") else: print("Access granted.")
Output:
pseudoAccess denied. You need moderator privileges.
7.7 Worked Example 1: Driving License Eligibility
python# runnable age = int(input("Enter your age: ")) passed_test = True has_glasses = True vision_corrected = False # whether glasses fix vision if age >= 18: print("Age requirement met.") if passed_test: print("Written test passed.") if has_glasses and not vision_corrected: print("License denied: Vision requirement not met.") elif has_glasses and vision_corrected: print("License approved (with corrective lenses restriction).") else: print("License approved! Full privileges.") else: print("License denied: Failed written test.") else: print("License denied: Under 18.")
7.8 Worked Example 2: Tax Calculator with Multiple Brackets
python# runnable income = float(input("Enter annual income: ₹")) age = int(input("Enter age: ")) # Determine tax rate if income <= 250000: tax = 0 print("No tax applicable.") elif income <= 500000: tax = (income - 250000) * 0.05 print("5% tax on income above ₹2.5L.") elif income <= 1000000: tax = 12500 + (income - 500000) * 0.20 print("₹12,500 + 20% on income above ₹5L.") else: tax = 112500 + (income - 1000000) * 0.30 print("₹1,12,500 + 30% on income above ₹10L.") # Senior citizen rebate if age >= 60: rebate = min(tax, 50000) tax -= rebate print(f"Senior citizen rebate: ₹{rebate:.0f}") print(f"Total tax payable: ₹{tax:.2f}")
7.9 Worked Example 3: Triangle Classifier
python# runnable a = float(input("Side 1: ")) b = float(input("Side 2: ")) c = float(input("Side 3: ")) # Check if valid triangle if a + b > c and a + c > b and b + c > a: print("Valid triangle.") if a == b == c: print("Type: Equilateral (all sides equal)") elif a == b or b == c or a == c: print("Type: Isosceles (two sides equal)") else: print("Type: Scalene (no sides equal)") # Check right-angled sides = sorted([a, b, c]) if abs(sides[0]**2 + sides[1]**2 - sides[2]**2) < 0.0001: print("Also: Right-angled triangle!") else: print("Invalid triangle. The sides don't satisfy triangle inequality.")
7.10 Worked Example 4: Validating Input with Multiple Conditions
python# runnable email = input("Enter email: ") # Validate email has_at = "@" in email has_dot = "." in email valid_length = 5 <= len(email) <= 100 no_spaces = " " not in email is_valid = has_at and has_dot and valid_length and no_spaces if is_valid: print("✓ Email format is valid.") if email.count("@") > 1: print("⚠ Warning: Multiple @ symbols found.") else: print("✗ Invalid email.") if not has_at: print("- Missing @ symbol") if not has_dot: print("- Missing dot (.)") if not valid_length: print("- Invalid length (need 5-100 chars)") if not no_spaces: print("- Contains spaces")
7.11 Worked Example 5: Rock-Paper-Scissors Logic
python# runnable player1 = input("Player 1 (rock/paper/scissors): ").lower() player2 = input("Player 2 (rock/paper/scissors): ").lower() valid = player1 in ("rock", "paper", "scissors") and player2 in ("rock", "paper", "scissors") if not valid: print("Invalid choice! Choose rock, paper, or scissors.") else: if player1 == player2: print("It's a tie!") elif (player1 == "rock" and player2 == "scissors") or \ (player1 == "scissors" and player2 == "paper") or \ (player1 == "paper" and player2 == "rock"): print("Player 1 wins!") else: print("Player 2 wins!")
📐 Key Concepts Reference
| Approach | When to Use | Example |
|---|---|---|
Nested if | Hierarchical decisions (B checked only if A passes) | if logged_in: if admin: |
elif chain | Mutually exclusive alternatives | if x > 0: elif x < 0: else: |
and/or | Combine independent conditions | if age >= 18 and has_ticket: |
| Short-circuit | Safe evaluation of risky expressions | if x != 0 and 10/x > 2: |
| Guard pattern | Check prerequisites first | if not user: return |
⚠️ Common Pitfalls
Pitfall 1: Deep Nesting (Diamond of Death)
The mistake: 5+ levels of nested
if — impossible to read or debug. Why: Each level adds mental overhead tracking which conditions are true. Fix: Use and/or, early returns in functions, or elif chains.Pitfall 2: Short-Circuit Surprises
The mistake: Relying on a function being called that never runs due to short-circuit. Fix: Put side-effect-free checks first in
and (the cheap, safe one). If the function MUST run, evaluate it separately before the condition.Pitfall 3: == True Is Redundant
The mistake:
if x == True: instead of if x: Fix: Python's if already checks truthiness. Write if x: for truthy/falsy, or if x is True: if you need the literal True.Pitfall 4: Not Handling Edge Cases in Nested Logic
The mistake: Only testing the "happy path." Example: Checking
if age >= 18: then nested if has_id: but not handling age < 18. Fix: Always include else branches, even if just a comment/placeholder.📝 Practice Questions
Q1: What does this code output?pythonx = 10 y = 20 if x > 5: if y > 15: print("A") else: print("B") else: print("C")Answer:pseudoA
x > 5→ True, enter outer if- Inside:
y > 15→ True, print "A" Q2: Simplify this nested code:pythonif a > 0: if b > 0: result = "Both positive"Answer:pythonif a > 0 and b > 0: result = "Both positive"Q3: What does this output?pythondef returns_false(): print("Hi!") return False if returns_false() and returns_false(): passAnswer:pseudoHi!Short-circuit: the firstreturns_false()returns False, soandshort-circuits. The second call NEVER happens. Only "Hi!" prints once. Q4: Write code that checks if a number is between 1 and 100 (inclusive) AND even.Answer:python# runnable n = 50 if 1 <= n <= 100 and n % 2 == 0: print(f"{n} is even and between 1 and 100")Q5: Fix this code to avoid ZeroDivisionError:pythonx = 0 if 10 / x > 2: print(">2")Answer:pythonx = 0 if x != 0 and 10 / x > 2: print(">2")Short-circuit ensures the division only happens whenx != 0. Q6: What's wrong with this code?pythonif age >= 18: print("Adult") if age >= 65: print("Senior") elif age >= 21: print("Can drink in US") else: print("Minor")Answer: The logic is mostly fine, but note:elif age >= 21is inside the outerifblock. It will only check ifage >= 18is True. For age 22: prints "Adult" then "Can drink in US" (correct). For age 70: prints "Adult" then "Senior" — and stops (correct, sinceelifwon't execute afterif age >= 65matched). Q7: Write a nested conditional that checks if a character is a letter, and if so, whether it's uppercase or lowercase.Answer:python# runnable ch = input("Enter a character: ") if ch.isalpha(): if ch.isupper(): print(f"'{ch}' is an uppercase letter.") else: print(f"'{ch}' is a lowercase letter.") else: print(f"'{ch}' is not a letter.")Q8: What's the output?pythona, b, c = 0, 5, 10 if a and b: print("1") elif b and c: print("2") elif a or b: print("3")Answer:pseudo2
a and b→0 and 5→0(falsy), skipb and c→5 and 10→10(truthy), enter! Print "2"- Rest skipped Q9: Write a program that prints "Weekend" if the day is Saturday or Sunday, "Weekday" otherwise.
Answer:python# runnable day = input("Enter day: ").lower() if day in ("saturday", "sunday"): print("Weekend") else: print("Weekday")Q10: What's the value of this expression?pythonx = 0 y = 5 result = (x != 0 and y / x > 2) or (y > 0) print(result)Answer:pseudoTrue
x != 0→0 != 0→ False- Short-circuit:
y / xNEVER evaluates (safe!)y > 0→5 > 0→ TrueFalse or True→ True
🔗 Cross-References
- Next Topic: Modules & Import
- Previous Topic: Conditionals — if/elif/else
- BSCS1001 Computational Thinking: Complex conditionals map to decision trees and flowcharts.
- Reference: Python for Everybody, Chapter 3 (Sections 3.5-3.8)
- Video: L22: Tutorial on if, else and else-if (elif) conditions Join Discord Previous6. ConditionalsNext8. Modules & Import