Python Basics — Truthy & Falsy Values

3 minute read

Truthy & Falsy Values

In Python, every value has a boolean identity. When used in a condition, values are automatically evaluated as either “truthy” (treated as True) or “falsy” (treated as False).

Complete Falsy Values List

These are all the values that evaluate to False in Python:

Value Type Description
False bool Boolean false
None NoneType Python’s null
0 int Integer zero
0.0 float Float zero
0j complex Complex zero
"" str Empty string
[] list Empty list
() tuple Empty tuple
{} dict Empty dictionary
set() set Empty set
range(0) range Empty range
frozenset() frozenset Empty frozenset

Everything else is truthy.

# Verify with bool()
print(bool(0))        # False
print(bool(""))       # False
print(bool([]))       # False
print(bool(None))     # False

print(bool(1))        # True
print(bool("hello"))  # True
print(bool([1, 2]))   # True
print(bool(-1))       # True

How if Statements Use Truthiness

When you write if some_value:, Python calls bool(some_value) behind the scenes:

name = "Alice"

# These are equivalent:
if name:
    print(f"Hello, {name}!")

if bool(name) == True:
    print(f"Hello, {name}!")

Output:

Hello, Alice!
Hello, Alice!

Pythonic Patterns

Check If a Collection Is Empty

my_list = [1, 2, 3]

# Not Pythonic
if len(my_list) > 0:
    print("List has items")

# Pythonic
if my_list:
    print("List has items")

Check If a String Is Non-Empty

username = input("Enter name: ")

# Not Pythonic
if username != "":
    print(f"Welcome, {username}")

# Pythonic
if username:
    print(f"Welcome, {username}")

Check for None

result = None

# Works — but less explicit
if result:
    print(result)

# Better — explicitly checks for None
if result is not None:
    print(result)

Why the distinction? if result: would also skip 0, "", and []. If those are valid values, use is not None instead.

Short-Circuit Evaluation in Context

Python’s and and or operators use short-circuit evaluation — they return the actual values, not just True/False:

or — Returns the First Truthy Value

name = "" or "Anonymous"
print(name)  # Anonymous

name = "Alice" or "Anonymous"
print(name)  # Alice
# Default value pattern
config_port = None
port = config_port or 8080
print(port)  # 8080

and — Returns the First Falsy Value (or the Last Value)

result = "hello" and "world"
print(result)  # world (both truthy — returns last)

result = "" and "world"
print(result)  # "" (first is falsy — returns it)

result = "hello" and 0
print(result)  # 0 (second is falsy — returns it)

Common Patterns

Guard Against Empty Data

def process_items(items):
    if not items:
        print("No items to process.")
        return

    for item in items:
        print(f"Processing: {item}")

process_items([])          # No items to process.
process_items(["a", "b"])  # Processing: a, Processing: b

Default Values with or

def greet(name=None):
    display = name or "Guest"
    print(f"Hello, {display}!")

greet("Alice")  # Hello, Alice!
greet()          # Hello, Guest!
greet("")        # Hello, Guest!

Conditional Assignment

scores = [85, 92, 78]
has_scores = bool(scores)
message = f"Average: {sum(scores)/len(scores):.1f}" if scores else "No scores"
print(message)  # Average: 85.0

Gotchas and Edge Cases

Gotcha 1: 0 and "" Are Valid but Falsy

count = 0  # Valid value, but falsy!

if count:
    print(f"Count is {count}")
else:
    print("No count")  # This runs — probably not what you wanted

Fix: Be explicit about what you’re checking:

if count is not None:
    print(f"Count is {count}")  # Count is 0

Gotcha 2: Empty String vs None

value = ""

# These behave differently:
if not value:           # True — empty string is falsy
    print("falsy")

if value is None:       # False — "" is not None
    print("is None")

Gotcha 3: or Doesn’t Always Work for Defaults

# Problem: 0 is a valid value but falsy
threshold = 0
limit = threshold or 100
print(limit)  # 100 — Wrong! We wanted 0

# Fix: Use a ternary or is None check
limit = threshold if threshold is not None else 100
print(limit)  # 0 — Correct!

Truthiness Comparison Table

Expression Result Why
bool(42) True Non-zero number
bool(-1) True Non-zero number
bool(0) False Zero
bool("hello") True Non-empty string
bool("") False Empty string
bool(" ") True Contains a space character
bool([0]) True Non-empty list (even with falsy element)
bool([]) False Empty list
bool(None) False None is always falsy

Summary

  • Falsy: False, None, 0, 0.0, "", [], (), {}, set(), range(0)
  • Truthy: Everything else
  • Use if my_list: instead of if len(my_list) > 0: — it’s more Pythonic
  • Use is not None when 0, "", or [] are valid values
  • or returns the first truthy value — useful for defaults
  • and returns the first falsy value or the last value
  • Be careful: 0 and "" are falsy but might be valid data

Next up: Practice Exercises →

Updated: