6 · Booleans: truthy, falsy & short-circuit
What evaluates to False in Python — and why `and`/`or` return values, not just True/False.
`and`/`or` return one of their operands, not necessarily `True` or `False` — that's the short-circuit rule.
Without this:
Without understanding truthy/falsy, a guard like `if weights:` silently passes when `weights` is an empty list `[]` — your model trains on nothing.
Python's bool type has exactly two values: True and False. But many other values behave like booleans in a conditional — they are truthy (treated as True) or falsy (treated as False). Knowing the falsy set by heart saves hours of debugging.
Python (in browser)
Memorise the falsy set: zero integers, zero float, empty string, empty collections, None, and False itself.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
and and or are short-circuit operators — they stop evaluating as soon as the result is determined, and they return the actual operand that decided the outcome, not a boolean.
Python (in browser)
Short-circuit evaluation is not just an optimisation — it's relied on idiomatically in Python to avoid expensive or crashing operations.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`id()` returns the memory address. Two equal lists are stored at different addresses — `is` checks the address, `==` checks the contents.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
What does `bool([])` return, and what does `[] == []` return?
- The falsy set: `0`, `0.0`, `""`, `[]`, `{}`, `set()`, `None`, `False`. Everything else is truthy.
- `and`/`or` return an operand, not always `True`/`False`. `x or default` is an idiomatic pattern for providing fallback values.
- `is` checks identity (same object in memory); `==` checks equality (same value). Only use `is` for `None`, `True`, `False`.
NumPy and Pandas boolean masks follow the same truthy semantics — `if df[mask]:` raises an error because a boolean Series is not a scalar. Guards like `if model is not None:` before calling `.predict()` use the identity rule correctly. Short-circuit `config.get('dropout') or 0.0` is standard for optional hyperparameters.
If you remove it: Misusing `==` for `None` checks passes linting but fails with numpy arrays (where `array == None` returns an array, not a scalar bool), causing cryptic `ValueError: The truth value of an array is ambiguous` crashes.