Python Conditionals: if, elif, and else Explained

Every useful program has to make decisions: should this crop be harvested? Can the player afford to buy seeds? Is the farm grid full? In Python, these decisions are expressed with conditional statements β€” if, elif, and else. Mastering conditionals means your code can react intelligently to any situation.

The if Statement

The simplest conditional runs a block of code only when a condition is True.

python
gold = 80
seed_cost = 50

if gold >= seed_cost:
    print("Purchasing seeds...")
    gold -= seed_cost
    print(f"Gold remaining: {gold}")

print("Done.")   # always runs

The body of the if block is indented by 4 spaces. Any line back at the original indentation level runs regardless of the condition.

elif and else

Use elif (short for "else if") to test multiple conditions in order. Only the first truthy branch runs. else is the catch-all that runs when nothing above matched.

python
water_level = 0.3   # 0.0 = bone dry, 1.0 = saturated

if water_level >= 0.8:
    status = "overwatered"
elif water_level >= 0.4:
    status = "well watered"
elif water_level >= 0.1:
    status = "needs water"
else:
    status = "critically dry"

print(f"Plot status: {status}")   # needs water
Remember: Python evaluates branches top-to-bottom and stops at the first match. Order matters β€” put the most specific conditions first.

Comparison Operators

Conditions are built from comparisons that evaluate to True or False:

  • == β€” equal to
  • != β€” not equal to
  • < β€” less than
  • > β€” greater than
  • <= β€” less than or equal to
  • >= β€” greater than or equal to
  • is β€” same object in memory (use with None)
  • in β€” membership in a list, string, or dict
python
days_grown = 4
crop = "wheat"
valid_crops = ["wheat", "carrot", "tomato"]

print(days_grown == 4)          # True
print(days_grown != 5)          # True
print(days_grown > 5)           # False
print(crop in valid_crops)      # True
print(crop is None)             # False

Boolean Operators: and, or, not

Combine multiple conditions with and, or, and not.

python
days_grown = 5
is_watered = True
HARVEST_DAYS = 5

# and: both conditions must be True
can_harvest = days_grown >= HARVEST_DAYS and is_watered
print(can_harvest)   # True

# or: at least one must be True
needs_attention = days_grown < 2 or not is_watered
print(needs_attention)   # False

# not: flips the boolean
print(not is_watered)    # False

Quick truth table for and and or:

  • True and True β†’ True
  • True and False β†’ False
  • False and False β†’ False
  • True or False β†’ True
  • False or False β†’ False

Truthy and Falsy Values

In Python, every value has an inherent boolean meaning. Values that act like False are called falsy; everything else is truthy.

  • Falsy: False, 0, 0.0, "", [], {}, None
  • Truthy: anything else β€” non-zero numbers, non-empty strings, non-empty lists
python
inventory = []

# Falsy check on an empty list
if not inventory:
    print("Inventory is empty β€” buy seeds!")

crop_name = "wheat"

# Truthy check on a non-empty string
if crop_name:
    print(f"Ready to plant {crop_name}")

Chaining Comparisons

Python allows you to chain comparison operators in a way that reads like math β€” much cleaner than two separate conditions joined by and.

python
temperature = 22

# Verbose version
if temperature >= 15 and temperature <= 30:
    print("Ideal growing conditions")

# Chained version β€” equivalent and easier to read
if 15 <= temperature <= 30:
    print("Ideal growing conditions")

Ternary Expression

When you want to assign one of two values based on a condition, the ternary (conditional) expression keeps it on one line.

python
days_grown = 6
HARVEST_DAYS = 5

# Ternary: value_if_true if condition else value_if_false
label = "mature" if days_grown >= HARVEST_DAYS else "growing"
print(label)   # mature

# Useful for display logic
icon = "🌾" if label == "mature" else "🌱"

Nested Conditionals

You can put an if inside another if. Use this sparingly β€” deep nesting quickly becomes hard to read. If you find yourself nesting three or more levels deep, consider refactoring into a function or using and/or to flatten the logic.

python
def try_harvest(plot, gold):
    if plot is not None:
        if plot["mature"]:
            profit = plot["value"] - plot["cost"]
            return gold + profit, None   # new gold, plot cleared
        else:
            print("Crop not ready yet.")
    else:
        print("Nothing planted here.")
    return gold, plot   # unchanged

Practical: is_mature() Before Harvest

Here's a complete harvest check that uses everything covered in this article β€” comparisons, boolean operators, truthy checks, and a clean if/elif/else chain:

python
CROP_DATA = {
    "wheat":  {"days": 5, "cost": 10, "value": 25},
    "carrot": {"days": 3, "cost": 5,  "value": 15},
    "tomato": {"days": 7, "cost": 15, "value": 40},
}

def harvest_check(plot, gold):
    """Return outcome message and updated gold."""
    if plot is None:
        return "Empty plot β€” nothing to harvest.", gold

    crop = CROP_DATA.get(plot["name"])
    if crop is None:
        return "Unknown crop type.", gold

    if plot["days"] >= crop["days"] and plot["watered"]:
        profit = crop["value"] - crop["cost"]
        return f"Harvested {plot['name']} for {profit} gold!", gold + profit
    elif plot["days"] >= crop["days"] and not plot["watered"]:
        return "Crop is dry β€” water first!", gold
    else:
        remaining = crop["days"] - plot["days"]
        return f"{remaining} day(s) until harvest.", gold