bool() Function Complexity¶
The bool() function converts an object to a boolean value using truthiness evaluation.
Complexity Analysis¶
| Case | Time | Space | Notes |
|---|---|---|---|
| Convert number (int, float, complex) | O(1) | O(1) | Zero check; does not grow with the value's size |
| Convert built-in container (str, list, dict, set, range, etc) | O(1) | O(1) | Empty check on the stored length; items are not counted |
Class defining __bool__() |
O(k) | O(1) | k = __bool__()'s cost (usually O(1)); __len__() is not called |
Class defining only __len__() |
O(k) | O(1) | k = __len__()'s cost |
| Class defining neither | O(1) | O(1) | Always True |
bool() makes at most one call to __bool__() or __len__(), and a custom
method's own time and space add to the row. The result is one of the two
singletons True and False, so nothing is allocated for it.
Basic Usage¶
Boolean Values¶
# O(1) - direct conversion
bool(True) # True
bool(False) # False
Integers and Floats¶
# O(1) - zero/non-zero check
bool(0) # False
bool(1) # True
bool(-1) # True
bool(0.0) # False
bool(3.14) # True
Strings¶
# O(1) - empty/non-empty check
bool("") # False (empty string)
bool("a") # True (non-empty)
bool("0") # True (non-empty, not zero!)
Collections¶
# O(1) - check if empty (uses __len__)
bool([]) # False
bool([1, 2, 3]) # True
bool({}) # False
bool({"a": 1}) # True
bool(set()) # False
bool({1, 2}) # True
bool(()) # False
bool((1, 2)) # True
None¶
# O(1) - None is always falsy
bool(None) # False
Complexity Details¶
Container Truthiness¶
# O(1) - uses __bool__() or __len__()
# Python checks for __bool__() first, then __len__()
class CustomClass:
def __init__(self, size):
self.size = size
def __len__(self):
# O(1) - just return stored size
return self.size
obj = CustomClass(0)
bool(obj) # False - calls __len__(), returns 0
obj = CustomClass(5)
bool(obj) # True - calls __len__(), returns 5
Custom __bool__() Method¶
# O(k) - depends on __bool__() implementation
class Expensive:
def __init__(self, data):
self.data = data
def __bool__(self):
# O(n) worst case - any() stops at the first truthy item
return any(self.data)
obj = Expensive([0, 0, 0])
bool(obj) # False - O(n), all three items checked
# Without __bool__, __len__() decides - O(1) for a list
# It answers a different question: non-empty, not "any item truthy"
class Efficient:
def __init__(self, data):
self.data = data
def __len__(self):
# O(1) - quick
return len(self.data)
obj = Efficient([0, 0, 0])
bool(obj) # True - O(1), calls __len__()
Truthiness Rules¶
# O(1) - these are always falsy:
bool(None) # False
bool(False) # False
bool(0) # False
bool(0.0) # False
bool(0j) # False (complex)
bool("") # False (empty string)
bool([]) # False (empty list)
bool({}) # False (empty dict)
bool(set()) # False (empty set)
bool(()) # False (empty tuple)
bool(range(0)) # False (empty range)
# O(1) - these values are truthy:
bool(True) # True
bool(1) # True
bool(-1) # True
bool(0.1) # True
bool("0") # True (non-empty!)
bool([0]) # True (non-empty!)
bool([None]) # True (non-empty!)
bool([False]) # True (non-empty!)
Common Patterns¶
Conditional Checks¶
# O(1) - implicit bool conversion
def process(items):
return len(items)
items = []
if items: # O(1) - checks truthiness
process(items)
# Explicit conversion
if bool(items): # O(1) - same thing
process(items)
# More Pythonic - just use implicit
if items: # Preferred
process(items)
Negation¶
# O(1) - logical not
not True # False
not False # True
# With objects
items = []
if not items: # O(1) - equivalent to if len(items) == 0
print("empty")
Filtering by Truthiness¶
# O(n) - check each item
items = [0, 1, "", "hello", [], [1], None, False, True]
# Remove falsy values - O(n)
truthy_items = [x for x in items if x]
# [1, "hello", [1], True]
# Using filter - O(n)
truthy_items = list(filter(bool, items))
# Same result, O(n)
Boolean Lists¶
# O(n) - convert each element
values = [0, 1, 2, 3, 0, 5]
bools = [bool(x) for x in values]
# [False, True, True, True, False, True]
# Using map - O(n)
bools = list(map(bool, values))
# Same result
Performance Patterns¶
Checking Container Emptiness¶
# All O(1) with __len__
items = [1, 2, 3]
if items: # O(1) - uses __len__()
pass
if len(items) > 0: # O(1) - explicit
pass
if len(items) != 0: # O(1) - also explicit
pass
# Idiomatic - let Python do implicit bool
if items: # Best
pass
vs Explicit Comparisons¶
obj = [1, 2, 3]
# Truthiness - O(1) for built-in types, else __bool__() or __len__()
if obj:
pass
# None check - O(1) for any type, but a different question:
# an empty list is not None
if obj is not None:
pass
# len() - for a type with no __bool__(), the same __len__() call
# that `if obj:` makes
if len(obj) > 0:
pass
Practical Examples¶
Default Parameter Handling¶
# O(1) - check if argument provided
default_value = 10
def process(value=None):
if value is None: # O(1)
value = default_value
return value
process(0) # 0 - `if not value:` would replace it with 10
# With optional list
def extend_list(items=None):
if items is None: # O(1)
items = []
return items
Validation¶
# O(1) - check required fields
def validate_data(data):
if not data: # O(1) - check if dict is empty
raise ValueError("Data required")
required_fields = ["id", "name"]
for field in required_fields:
if not data.get(field): # O(1) - get and check
raise ValueError(f"{field} required")
Boolean Aggregation¶
# O(n) - check multiple conditions
items = [1, 2, 3, 4, 5]
# Check if any item is truthy (short-circuits)
if any(items): # Stops at the first truthy item - here the first
pass
# Check if all items are truthy
if all(items): # O(n) - checks all
pass
# With conditions
if any(x > 10 for x in items): # O(n) or early exit
pass
if all(x > 0 for x in items): # O(n) or early exit
pass
Edge Cases¶
Empty vs None vs False¶
# All falsy, but different
bool(None) # False - no value
bool([]) # False - empty container
bool(False) # False - explicit false
bool("") # False - empty string
# All truthy
bool([0]) # True - non-empty
bool([None]) # True - non-empty
bool([False])# True - non-empty
Custom Falsy Objects¶
# O(1) - return False from __bool__
class AlwaysFalse:
def __bool__(self):
return False
obj = AlwaysFalse()
bool(obj) # False
# But object exists
if obj: # False
pass
if obj is not None: # True - object exists!
pass
Division by Zero Check¶
# O(1) - check for zero before division
divisor = 4
if divisor: # O(1) - checks if non-zero
result = 100 / divisor
else:
result = None
# vs explicit check
if divisor != 0: # O(1)
result = 100 / divisor
Best Practices¶
✅ Do:
- Use implicit truthiness:
if items:notif len(items) > 0: - Check
is Noneexplicitly:if value is None:notif not value: - Use
bool()to convert to boolean explicitly when needed - Define
__bool__()on a class whose__len__()is expensive, so truth tests skip__len__()
❌ Avoid:
- Confusing empty with False:
[]andFalseare both falsy but different - Using
bool()unnecessarily in conditions - Assuming all falsy values are False
- Complex
__bool__()implementations (should be O(1))
Version Notes¶
- Python 2.x: Works with
__nonzero__()instead of__bool__() - Python 3.x: Uses
__bool__()method - Python 3.14+:
bool(NotImplemented)raisesTypeError; 3.11 to 3.13 returnTruewith aDeprecationWarning - All versions: Falsy values consistent (None, False, 0, "", [], {}, etc.)