MOD-07 · Sequence #7 · Python Logic

Python Booleans & Logical Evaluation

Python booleans (True and False) inherit from int. Python evaluates expressions in boolean contexts using the concept of truthiness. Logical operators (and, or, not) employ short-circuit evaluation, returning the actual operand value rather than a forced boolean.

Live Interactive Code Snippet (Python 3.12 CPython WASM) Open in Practice Mode →
print(bool("Hello"))  # True
print(bool([]))       # False (empty collection is falsy)

Core Principles & Mental Models

1. Truthy vs. Falsy Values

Standard Boolean Testing Protocol

  • In Python, every object has a boolean value defined by its __bool__() or __len__() method.
  • Falsy values include: None, False, zero in any numeric type (0, 0.0, 0j), empty sequences and collections ("", (), [], {}, set(), range(0)).
  • All other values are Truthy by default.
items = []
if not items:
    print("Collection is empty! (Pythonic)")
# Avoid: if len(items) == 0: (redundant in Python)
💡 Key Takeaway: Check for empty containers by testing their truthiness directly: if not my_list:

2. Short-Circuit Evaluation and Return Values

and / or Return the Deciding Operand

  • In Python, `a or b` evaluates `a`. If `a` is truthy, it immediately returns `a` without ever evaluating `b`. If `a` is falsy, it evaluates and returns `b`.
  • Similarly, `a and b` evaluates `a`. If `a` is falsy, it immediately returns `a`. If `a` is truthy, it returns `b`.
  • This allows elegant fallback patterns like `user_name = input_name or "Anonymous"`.
result1 = "Default" or "Fallback"
result2 = "" or "Fallback"
result3 = [1, 2] and [3, 4]
result4 = [] and [3, 4]
print("result1:", repr(result1))
print("result2:", repr(result2))
print("result3:", repr(result3))
print("result4:", repr(result4))
💡 Key Takeaway: Python logical operators return the operand that terminated evaluation, not necessarily True or False.

Interactive Walkthrough Examples

Short-Circuit Guarding Against ZeroDivisionError (Intermediate)

Using `and` to guard against illegal mathematical operations without nested ifs.

def safe_divide(numerator, denominator):
    # If denominator is 0 (falsy), short-circuits before the division executes!
    return denominator != 0 and (numerator / denominator)

print("Safe divide 10 / 2:", safe_divide(10, 2))
print("Safe divide 10 / 0:", safe_divide(10, 0))

Explanation: Because denominator != 0 is False, the second operand is never evaluated, preventing ZeroDivisionError.

Common Misconceptions & Exam Traps

Common Pitfall: Using `x is True` Instead of `if x:`

`is True` checks memory identity with the boolean singleton True, which fails for truthy values like non-empty lists.

Buggy Code
val = [1, 2, 3]
if val is True:  # Evaluates to False! val is a list, not the singleton True.
    print("Has items")
Correct Solution
val = [1, 2, 3]
if val:  # Evaluates truthiness correctly
    print("Has items")

Exam Trap Note: Never write `if x == True:` or `if x is True:`. Simply write `if x:`.

Conceptual Knowledge Self-Check Quiz

Q1: What is the evaluated output of `[] or "cano(PY)code"`?

  1. False
  2. True
  3. "cano(PY)code"
  4. []

`[]` is falsy, so the `or` operator moves to the second operand and evaluates/returns `"cano(PY)code"`.

Algorithmic Practice Challenges

Idiomatic Best Practices

  • ✅ Use `if not items:` to check if a list, dictionary, or string is empty.
  • ✅ Rely on short-circuiting to provide sensible default parameters.

All 26 Curriculum Modules