Web Analytics

Return Values

Intermediate ~20 min read

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.

Output
Click Run to execute your code
Return Immediately Exits: When Python encounters a 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.

Output
Click Run to execute your code
Tuple Unpacking: When a function returns multiple values as a tuple, you can unpack them directly: 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.

Output
Click Run to execute your code
Print Returns None! 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.

Output
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)
Output
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 value exits function and sends value back
  • No return: Functions without return (or bare return) return None
  • Multiple values: return a, b, c returns 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!