Booleans in Python

Every decision your code makes — every if, every loop condition, every permission check — ultimately comes down to python booleans. This is one of the smaller data types in Python, but understanding it properly (including some of its less obvious behavior) makes reading and writing conditional logic much more natural.

What is a Boolean in Python?

A Boolean is a data type that represents exactly two possible values: True and False.

is_active = True
is_deleted = False

print(type(is_active))   # <class 'bool'>
bool is technically a subclass of int

Here's a detail that surprises a lot of beginners: Python's bool type is actually a subclass of int. True behaves as 1, and False behaves as 0, in any context that expects a number:

print(True == 1)    # True
print(False == 0)   # True
print(True + True)  # 2 — True is treated as 1 in arithmetic

This isn't just trivia — it has real practical uses, covered later in this article. For now, the key takeaway is: True and False are Booleans first, but they're numbers underneath.

Getting Booleans from Comparisons

Most Booleans in real code don't get typed directly as True or False — they're the result of a comparison.

Comparison operators

Python's comparison operators all evaluate to a Boolean:

print(5 == 5)    # True  — equal to
print(5 != 3)    # True  — not equal to
print(5 > 3)     # True  — greater than
print(5 < 3)     # False — less than
print(5 >= 5)    # True  — greater than or equal to
print(5 <= 4)    # False — less than or equal to
Controlling program flow with if statements

This is where Booleans earn their keep — every if statement is evaluating a Boolean expression to decide which branch of code to run:

age = 20

if age >= 18:
    print("Access granted")
else:
    print("Access denied")
Practical example: checking eligibility
account_balance = 150
withdrawal_amount = 200

can_withdraw = account_balance >= withdrawal_amount
print(can_withdraw)   # False

if can_withdraw:
    print("Withdrawal approved")
else:
    print("Insufficient funds")

Notice that can_withdraw stores the result of the comparison as a Boolean variable — a common and readable pattern, especially once the condition gets more complex.

Logical Operators: and, or, not

Real-world decisions usually involve more than one condition at a time. Python's logical operators — and, or, not — let you combine or invert Boolean values.

and

and returns True only if both conditions are true:

print(True and True)    # True
print(True and False)   # False
print(False and False)  # False
or

or returns True if at least one condition is true:

print(True or False)    # True
print(False or False)   # False
print(True or True)     # True
not

not simply flips a Boolean's value:

print(not True)    # False
print(not False)   # True
Combining conditions in practice
has_ticket = True
is_adult = False

can_enter = has_ticket and is_adult
print(can_enter)   # False — both conditions must be True

can_enter_with_guardian = has_ticket and (is_adult or True)  # True represents "has guardian" here

Stringing together conditions like this — has_ticket and is_adult, or more complex combinations — is how most real decision logic in Python actually gets written.

Truthy and Falsy Values

This is the part of python booleans that catches beginners off guard the most: you don't need an actual True or False to use a value in a Boolean context. Python evaluates any value for its "truthiness" when it appears in an if statement or similar context.

The complete list of falsy values

Only a specific, short list of values are considered falsy in Python:

False
None
0
0.0
""      # empty string
[]      # empty list
{}      # empty dictionary
()      # empty tuple
Everything else is truthy

Any value not on that list — a non-empty string, a non-zero number, a non-empty list — is treated as truthy:

if "hello":       # non-empty string — truthy
    print("This runs")

if []:             # empty list — falsy
    print("This does not run")

if 0:              # falsy
    print("This does not run either")

if 42:             # truthy
    print("This runs")
Practical implications for writing concise checks

Understanding truthy/falsy values lets you write shorter, more idiomatic conditionals. Instead of:

my_list = []

if len(my_list) == 0:
    print("List is empty")

You can write:

if not my_list:
    print("List is empty")

Both do exactly the same thing, but the second version is the style you'll see far more often in real Python code — it reads naturally and avoids an unnecessary length check.

The bool() Function and Practical Uses

Explicit conversion with bool()

The bool() function lets you explicitly check or convert any value's truthiness:

print(bool(""))       # False
print(bool("hi"))     # True
print(bool(0))        # False
print(bool(-5))       # True — any nonzero number is truthy, including negatives
print(bool([]))       # False
print(bool([1, 2]))   # True

This is useful any time you want to confirm how Python will treat a value in a conditional, without writing a full if statement to test it.

Booleans as numbers

Because True behaves as 1 and False behaves as 0, you can use Booleans directly in arithmetic — a genuinely useful trick, particularly for counting how many items in a collection meet some condition:

scores = [85, 42, 91, 33, 76]
passing_scores = [score >= 50 for score in scores]
print(passing_scores)          # [True, False, True, False, True]

count_passing = sum(passing_scores)
print(count_passing)            # 3 — sum() adds True values as 1

That last line works because sum() treats each True as 1 and each False as 0 — a compact, common pattern for counting matches without writing a manual loop and counter.

A note on custom objects and __bool__()

For more advanced use cases: when you define your own classes, Python lets you control how instances of that class behave in a Boolean context by defining a __bool__() method. By default, custom objects are always truthy, but implementing __bool__() lets you customize that — for example, making an empty custom container object evaluate as falsy, the same way an empty list does. This is a more advanced topic you won't need right away, but it's worth knowing it exists as you move beyond the basics.