if

Python tests truthiness, not "== True": 0, empty strings, empty containers and None all count as false. elif chains tests, and only the first true branch runs.

Control flowPython 3 (all)Live demo
if
if condition:
    body
if / elif / else
if test1:
    first
elif test2:
    second
else:
    fallback
conditional expression
x = a if condition else b
Use for
if x: / if a < x <= b: / elif for the next test / y = a if c else b
Result
a statement — runs at most one branch; the ternary form is an expression
Pairs with
and, or, not, in, is, else, chained comparisons
Watch out
x == 1 or 2 is always true; the string "False" is truthy

Demo

Live evaluation
Is the value truthy? Type anything — a number, text, or nothing at all.
Try:
Inputs
valueint | float | strnumber or text
Code
value = 0
verdict = "falsy"
if value:
    verdict = "truthy"
verdict
Result
'falsy'

In the if tab, the condition is not compared with True — Python asks bool(value). Zero of any number type and the empty string are false; a single space and the text "False" are non-empty strings, so they are true. In the if / elif / else tab, 90 gets an A because the >= 90 test comes first; every later elif is skipped once one branch has run. In the x if c else y tab, the upper bound 10 is excluded because the chain reads n < 10.

Syntax slots

NameTypeRequiredDescription
conditionexpressionyesAny value. Python calls bool() on it: 0, 0.0, "", [], {}, set(), None and False are false; almost everything else is true.
bodyblockyesRuns when the condition is truthy. Must not be empty — write pass for a placeholder.
elifblocknoAny number of further tests. Checked top to bottom only while every test above was false; the first true one wins.
elseblocknoRuns when no if / elif test was true. At most one, always last.

Common patterns

Guard clause
Handle the bad case first and leave early, instead of nesting the happy path.
def area(w, h):
    if w < 0 or h < 0:
        raise ValueError("negative size")
    return w * h
Empty-or-None check
if not items covers None, [] and "" in one test. Use is None when an empty value is valid.
def first(items):
    if not items:
        return None
    return items[0]
Membership instead of or-chains
in a set / tuple replaces x == a or x == b or x == c.
def is_weekend(day):
    return day in {"sat", "sun"}
Default with the conditional expression
Pick a value in one line; only the chosen side is evaluated.
def label(n):
    return "item" if n == 1 else "items"

Examples

1. if / elif / else
t = 18 if t < 0: print('freezing') elif t < 20: print('cool') else: print('warm')
Returns
cool
2. Falsy values
[bool(v) for v in (0, 0.0, '', [], {}, None)]
Returns
[False, False, False, False, False, False]
3. Non-empty is truthy — even "False"
[bool(v) for v in ('False', '0', ' ', [0], -1)]
Returns
[True, True, True, True, True]
4. Chained comparison
x = 5 1 < x < 10
Returns
True
5. Chains compare neighbours only
1 < 3 > 2
Returns
True
6. Conditional expression
n = 3 'odd' if n % 2 else 'even'
Returns
'odd'
7. Only the first true branch runs
x = 100 if x > 10: print('big') elif x > 50: print('huge')
Returns
big
8. else also belongs to loops and try
for n in []: pass else: print('loop else') try: pass except ValueError: pass else: print('try else')
Returns
loop else try else

Pitfalls

1. x == a or b is always true
It parses as (x == a) or b, and a non-empty b is truthy on its own. Compare each value, or use in.
or-chain of values
answer = 'no'
if answer == 'y' or 'yes':
    print('accepted')
accepted
membership test
answer = 'no'
if answer in ('y', 'yes'):
    print('accepted')
else:
    print('rejected')
rejected
2. Separate ifs instead of elif
Independent if statements are all tested, so a value can match several branches. elif stops at the first match.
three ifs
n = 95
hits = []
if n > 50:
    hits.append('pass')
if n > 90:
    hits.append('top')
hits
['pass', 'top']
most specific first + elif
n = 95
if n > 90:
    grade = 'top'
elif n > 50:
    grade = 'pass'
grade
'top'
3. if not x when 0 is a valid value
if not x is also true for 0 and "". When only None means missing, test is None.
truthiness test
discount = 0
if not discount:
    discount = 10
discount
10
is None
discount = 0
if discount is None:
    discount = 10
discount
0
4. Using = instead of == in a condition
Assignment is a statement, so it is a syntax error in an if test (the walrus := is the expression form).
single =
compile('if x = 5:\n    pass', '<demo>', 'exec')
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
comparison
x = 5
if x == 5:
    print("five")
five

When to use

Use it
  • Choosing between actions based on a condition
  • Guard clauses that reject bad input early
  • Picking one of two values inline with a if c else b
Reach for something else
  • Long elif chains mapping values to values → a dict lookup
  • Matching on the shape of data (lists, dicts, objects) → match (3.10+)
  • Returning a bool from a test → return the test itself, not if ...: return True

Notes

CPython impl
The condition is evaluated once and converted with bool(), which calls __bool__, then falls back to __len__; objects with neither are always true
Chaining
a < b < c evaluates b only once and stops at the first false comparison — it is a and b < c, not (a < b) < c
else
else is shared with for / while (runs when no break happened) and try (runs when no exception was raised)

FAQ

It is spelled elif. You can write else: followed by an indented if, but that nests one level deeper for each test; elif keeps the whole chain flat. There is no switch statement — use elif, a dict lookup, or match (3.10+).