In Python, None represents the absence of a value. It's common to need to provide a default value when a variable might be None.
This guide explores various methods for handling this, including conditional expressions (the ternary operator), the or operator, and best practices for function arguments.
Using Conditional Expressions (Ternary Operator)
A conditional expression (often called a "ternary operator") provides a concise way to assign a default value if a variable is None:
def example():
my_var = None
return "default value" if my_var is None else my_var
print(example()) # Output: default valueAlternative syntax, same result:
def example():
my_var = None
return my_var if my_var is not None else "default value"
print(example()) # Output: default value"default value" if my_var is None else my_varreads as: "Return 'default value' ifmy_varisNone; otherwise, returnmy_var." Theisoperator is best practice for checking for the singletonNone.
You can use this also outside a function:
my_var = None
my_var = "default value" if my_var is None else my_var
print(my_var) # Output: default valueUsing the or Operator (for Falsy Values)
The or operator can be used to set a default value, but be aware of its limitations:
def example():
my_var = None
return my_var or "default value"
print(example()) # Output: default value
my_var = None
my_var = my_var or "default value"
print(my_var) # Output: default value- The
oroperator returns the left operand if it's truthy; otherwise, it returns the right operand.
print(0 or 'default value') # Output: default value (0 is falsy)
print("" or 'default value') # Output: default value (empty string is falsy)
print('hello' or 'default value') # Output: hello ('hello' is truthy)Default Arguments in Functions
None is frequently used as a default argument value in function definitions:
def get_employee(name=None, age=None):
return {'name': name, 'age': age}
print(get_employee()) # Output: {'name': None, 'age': None}
print(get_employee(age=30)) # Output: {'name': None, 'age': 30}
print(get_employee('Tom Nolan', 30)) # Output: {'name': 'Tom Nolan', 'age': 30}- Default arguments allow you to call the function without specifying those arguments, providing flexibility.
The Mutable Default Argument Trap (and how to avoid it)
Never use mutable objects (like lists or dictionaries) as default argument values directly. This is a classic Python "gotcha":
def get_address(address={}): # DANGEROUS! Don't do this.
return address
addr1 = get_address()
addr2 = get_address()
addr1['country'] = 'Chile'
print(addr1) # Output: {'country': 'Chile'}
print(addr2) # Output: {'country': 'Chile'} <-- Unexpected!- The same empty dictionary (
{}) is created once when the function is defined, and then reused for every call whereaddressis not provided. Modifyingaddr1also modifiesaddr2because they both refer to the same dictionary object.
The Correct Way: Use None as the default, and create the mutable object inside the function:
def get_address(address=None):
if address is None:
address = {} # Create a NEW dictionary each time
return address
addr1 = get_address()
addr2 = get_address()
addr1['country'] = 'Chile'
print(addr1) # Output: {'country': 'Chile'}
print(addr2) # Output: {} (correct - a new, empty dictionary)- By using
Noneas the default, and creating a new dictionary inside the function, each call gets its own independent dictionary. This avoids the shared mutable default problem.