Return Values
Functions don't just perform actions - they can also compute and send back
results. The return statement is how functions communicate their output back
to the code that called them. Understanding return values is crucial for writing functions
that can be composed, tested, and reused effectively!
Basic Return Statements
The return statement immediately exits the function and sends a value back
to the caller. If a function doesn't have a return statement, or has return
without a value, it returns None by default.
Click Run to execute your code
return
statement, it immediately leaves the function. Any code after the return statement in
that code path will never execute. This makes return useful for "early exits" when
validation fails.
Returning Multiple Values
Python makes it easy to return multiple values from a function. You can return a tuple (the most common approach), a dictionary (for named values), a list, or even a named tuple for the best of both worlds.
Click Run to execute your code
min_val, max_val = get_min_max(nums). This
is cleaner than result = get_min_max(nums); min_val = result[0]. Use
named tuples when the meaning of each position isn't obvious.
Return vs Print
A common beginner confusion: print() displays output to the screen,
while return sends data back to the caller. Functions that print can't
be composed or tested easily - always prefer return for reusable functions.
Click Run to execute your code
print() always returns None,
not the string it displays. If you write result = print("Hello"), result
will be None. Use print for user output, return for function output.
Practical Return Patterns
Professional Python code uses return in many patterns: early returns for validation, guard clauses for cleaner logic, factory functions to create objects, and result patterns for error handling.
Click Run to execute your code
Common Mistakes
1. Using print instead of return
# Wrong - can't use the result
def add(a, b):
print(a + b)
result = add(3, 5) # result is None!
# result + 10 would cause TypeError
# Correct - return the value
def add(a, b):
return a + b
result = add(3, 5) # result is 8
print(result + 10) # Works: 18
2. Forgetting to capture the return value
def calculate_tax(amount):
return amount * 0.1
# Wrong - return value is lost
calculate_tax(100)
# The 10.0 is calculated but never stored
# Correct - capture the result
tax = calculate_tax(100)
print(f"Tax: ${tax}")
3. Unreachable code after return
# Wrong - cleanup never runs!
def get_data():
return fetch_from_database()
close_connection() # Never executes!
# Correct - use try/finally or context manager
def get_data():
try:
return fetch_from_database()
finally:
close_connection() # Always runs
4. Inconsistent return types
# Confusing - returns different types
def find_user(user_id):
if user_id in database:
return database[user_id] # Returns dict
return "Not found" # Returns string!
# Better - consistent return type
def find_user(user_id):
if user_id in database:
return database[user_id]
return None # Always returns dict or None
# Or return a result tuple
def find_user(user_id):
if user_id in database:
return True, database[user_id]
return False, None
5. Returning inside a loop without break logic
# Wrong - only checks first item
def contains_even(numbers):
for n in numbers:
if n % 2 == 0:
return True
return False # Returns on first iteration!
contains_even([1, 2, 3]) # Returns False (wrong!)
# Correct - check all items
def contains_even(numbers):
for n in numbers:
if n % 2 == 0:
return True
return False # Only after loop completes
contains_even([1, 2, 3]) # Returns True (correct)
Exercise: Statistics Function
Task: Create a function that returns statistics about a list of numbers.
Requirements:
- Accept a list of numbers
- Return a dictionary with: min, max, sum, and average
- Handle empty list case (return None or empty dict)
Click Run to execute your code
Show Solution
def get_stats(numbers):
"""Return statistics about a list of numbers."""
if not numbers:
return None
return {
"min": min(numbers),
"max": max(numbers),
"sum": sum(numbers),
"average": sum(numbers) / len(numbers)
}
# Test it
stats = get_stats([1, 2, 3, 4, 5])
print(f"Stats: {stats}")
print(f"Average: {stats['average']}")
empty_stats = get_stats([])
print(f"Empty: {empty_stats}")
Summary
- Return basics:
return valueexits function and sends value back - No return: Functions without return (or bare
return) returnNone - Multiple values:
return a, b, creturns a tuple - Unpack:
x, y, z = func()unpacks returned tuple - Return vs print: Return sends data back; print displays to screen
- Early return: Use return to exit early on validation failure
- Consistency: Return the same type(s) from all code paths
What's Next?
Now that you understand how functions communicate through arguments and return values, let's explore Variable Scope - understanding where variables exist and how Python looks them up. This is essential for avoiding bugs and writing cleaner code!
Enjoying these tutorials?