Mathew K Analytics

Lesson 4 · Python data types deep dive

Python Booleans & None Explained: Truthy vs Falsy | Data Types #4

Video four of the twelve-part series: bool and None, two small types with outsized influence on how every if statement, loop, and comparison in Python…

⬇ Download notebookOpen in Colab ↗

What you'll learn

Data

No separate download needed — the notebook creates or downloads everything it uses.

📓 Full notebook

Download .ipynb

Python Data Types Deep-Dive, Video 4: Booleans and None (bool, NoneType)#

  • Video four of the twelve-part series: bool and None, two small types with outsized influence on how every if statement, loop, and comparison in Python actually behaves.
  • Truthiness rules for every other type, short-circuit evaluation, and the real difference between is and ==.
  • Let's get into it.

Part 1: bool Is a Subclass of int#

print(type(True))
print(isinstance(True, int))
print(issubclass(bool, int))
print(True == 1)
print(False == 0)
print(True + True)
print(True * 5)
<class 'bool'>
True
True
True
True
2
5

Part 2: Truthy and Falsy Values#

falsy_values = [False, None, 0, 0.0, 0j, '', [], (), {}, set(), range(0)]
for value in falsy_values:
    print(f'{value!r} is falsy: {not bool(value)}')
False is falsy: True
None is falsy: True
0 is falsy: True
0.0 is falsy: True
0j is falsy: True
'' is falsy: True
[] is falsy: True
() is falsy: True
{} is falsy: True
set() is falsy: True
range(0, 0) is falsy: True
truthy_examples = [True, 1, -1, 0.1, 'False', ' ', [0], (0,), {'a': 1}]
for value in truthy_examples:
    print(f'{value!r} is truthy: {bool(value)}')
True is truthy: True
1 is truthy: True
-1 is truthy: True
0.1 is truthy: True
'False' is truthy: True
' ' is truthy: True
[0] is truthy: True
(0,) is truthy: True
{'a': 1} is truthy: True

Part 3: The bool() Constructor#

print(bool(42))
print(bool(0))
print(bool('hello'))
print(bool(''))
print(bool([1, 2, 3]))
print(bool(None))
print(bool(bool))
True
False
True
False
True
False
True

Part 4: Comparison Operators Return bool#

is_adult = 25 >= 18
print(is_adult)
print(type(is_adult))
has_items = 3 in [1, 2, 3, 4]
print(has_items)
is_same_object = [] is []
print(is_same_object)
True
<class 'bool'>
True
False

Part 5: Boolean Operators and Short-Circuit Evaluation#

print(3 and 5)
print(0 and 5)
print(3 or 5)
print(0 or 5)
print(not 3)
print(not 0)
5
0
3
5
False
True
def expensive_check():
    print('expensive_check actually ran')
    return True
print('--- with False and ---')
result = False and expensive_check()
print('--- with True or ---')
result = True or expensive_check()
--- with False and ---
--- with True or ---

Part 6: The Common x or default Idiom#

def greet(name=None):
    display_name = name or 'friend'
    return f'Hello, {display_name}!'
print(greet('Ana'))
print(greet())
print(greet(''))
Hello, Ana!
Hello, friend!
Hello, friend!

Part 7: Inherited int Methods on bool#

print(True.bit_length())
print(False.bit_length())
print(True.bit_count())
print(True.to_bytes(1, byteorder='big'))
print(True.as_integer_ratio())
print(True.numerator, True.denominator)
print(True.real, True.imag)
print(True.conjugate())
1
0
1
b'\x01'
(1, 1)
1 1
1 0
1

Part 8: Counting With sum() on Booleans#

scores = [45, 78, 92, 61, 88, 34, 95]
passing = [score >= 60 for score in scores]
print(passing)
print(sum(passing))
print(f'{sum(passing)} out of {len(scores)} passed')
[False, True, True, True, True, False, True]
5
5 out of 7 passed

Part 9: None, the Absence of a Value#

value = None
print(value)
print(type(value))
print(type(None))
another_none = None
print(value is another_none)
None
<class 'NoneType'>
<class 'NoneType'>
True

Part 10: is None Versus == None#

class WeirdEquality:
    def __eq__(self, other):
        return True
weird = WeirdEquality()
print(weird == None)
print(weird is None)
True
False
import warnings
with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter('always')
    exec('result = (5 == None)')
print(result)
print(len(caught) >= 0)
False
True

Part 11: The Mutable Default Argument Pitfall#

def broken_add_item(item, target_list=[]):
    target_list.append(item)
    return target_list
print(broken_add_item('a'))
print(broken_add_item('b'))
['a']
['a', 'b']
def fixed_add_item(item, target_list=None):
    if target_list is None:
        target_list = []
    target_list.append(item)
    return target_list
print(fixed_add_item('a'))
print(fixed_add_item('b'))
['a']
['b']

Part 12: None in Conditions and Function Return Values#

def no_explicit_return(x):
    print(f'Processing {x}')
result = no_explicit_return(5)
print(result)
print(result is None)
Processing 5
None
True
def find_first_negative(numbers):
    for n in numbers:
        if n < 0:
            return n
    return None
result = find_first_negative([3, 7, -2, 9])
if result is not None:
    print(f'Found: {result}')
else:
    print('No negative number found')
Found: -2

Part 13: Common Patterns and Pitfalls#

ages = [22, 35, 41, 19, 28]
print(all(age >= 18 for age in ages))
print(any(age >= 40 for age in ages))
print(all([]))
print(any([]))
True
True
True
False
flag = True
if flag:
    print('Correct idiom: works for any truthy value')
if flag is True:
    print('Fragile idiom: fails silently for truthy non-bool values like 1')
flag_as_int = 1
print(flag_as_int is True)
Correct idiom: works for any truthy value
Fragile idiom: fails silently for truthy non-bool values like 1
False

Wrap-Up: What You Learned#

  • bool is a genuine subclass of int, with True as one and False as zero in every arithmetic context.
  • The complete, exhaustive list of falsy values, and how bool() applies those rules explicitly.
  • Comparison operators all return real bool values.
  • Short-circuit evaluation: and and or return an actual operand, not just True or False, enabling the x-or-default idiom.
  • Every inherited int method still technically works on bool.
  • Counting truthy conditions with sum(), and checking whole collections with all() and any().
  • None: the one-and-only NoneType singleton, why is None beats == None, the mutable default argument pitfall, and implicit None returns.
  • Next up: str, the largest built-in type in this series, with all forty-seven of its methods covered one at a time.

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.