← Previous

Lesson 10 · Python

Returns

~30 min

1. Returns in Python

Functions are workhorses in Python. They can take inputs (arguments), process data, and execute commands. However, a function's real superpower is its ability to send data back to the main program using the return statement. Mastering return values allows you to chain functions together, store output in variables, and build complex software systems.

Learning Objectives

  • Understand the purpose and behavior of the return statement in Python.
  • Master the fundamental difference between print() and return.
  • Learn how to return multiple values from a single function using tuple unpacking.
  • Use early returns (guard clauses) to streamline function control flow.

2. What is the return Statement?

The return statement is used inside a function to exit the function and hand a value back to the caller. When Python encounters a return keyword, execution of that function ends immediately. Whatever expression follows the return keyword is evaluated and sent back as the result of the function call.

Think of calling a function like giving an assignment to a coworker. If you ask them to perform a calculation, you don't just want them to write the answer on a sticky note and throw it in the trash; you want them to hand the final report back to you so you can use it in your next meeting. The return statement is that handover.

Python code example:

def square(number):
    return number * number

# The function returns 25, which gets stored in 'result'
result = square(5)

print(result)       # Output: 25
print(result + 10)  # Output: 35 (we can use 'result' in further math!)

3. Print vs Return: The Golden Rule

One of the most common hurdles for Python beginners is confusing print() with return. They may look like they do similar things when running code in a console, but they serve completely different purposes:

  • print(): Displays text on the screen for a human to see. It does not save or pass data anywhere. A function that only prints returns None by default.
  • return: Passes data back to your code so it can be saved in a variable, passed into another function, or used in logical comparisons. It does not automatically display text on the screen.

Python code example:

# Example A: Using print()
def add_with_print(a, b):
    print(a + b)

# Example B: Using return
def add_with_return(a, b):
    return a + b

val1 = add_with_print(3, 4)   # Displays 7 on screen, but val1 holds None
val2 = add_with_return(3, 4)  # Nothing displays on screen, but val2 holds 7

print("val1 is:", val1)  # Output: val1 is: None
print("val2 is:", val2)  # Output: val2 is: 7

4. Returning Multiple Values

Unlike many other programming languages, Python allows a function to return multiple values at once. You simply separate the return values with commas. Under the hood, Python automatically packs these values into a single tuple, which you can easily unpack into separate variables.

Python code example:

def get_user_stats():
    name = "Alex"
    level = 42
    score = 9850
    return name, level, score  # Returns a tuple of 3 items

# Unpacking the returned values into three distinct variables
player_name, player_level, player_score = get_user_stats()

print(f"Player: {player_name}")    # Output: Player: Alex
print(f"Level: {player_level}")    # Output: Level: 42
print(f"Score: {player_score}")    # Output: Score: 9850

5. Early Returns & Control Flow

Because the return statement immediately stops function execution, you can use it to exit a function early if certain conditions aren't met. This pattern is often called a guard clause, and it helps prevent deeply nested if/else blocks, making your code cleaner and easier to read.

Python code example:

def divide_numbers(numerator, denominator):
    # Guard clause: check for invalid input early
    if denominator == 0:
        return "Error: Cannot divide by zero!"
    
    # If denominator is not 0, execution continues here
    return numerator / denominator

print(divide_numbers(10, 2))  # Output: 5.0
print(divide_numbers(10, 0))  # Output: Error: Cannot divide by zero!

6. Real World Example

Imagine you are building a feature for a health app that calculates a user's Body Mass Index (BMI) and determines their health category based on the numerical result.

def calculate_bmi(weight_kg, height_m):
    # Calculate raw BMI score
    bmi = weight_kg / (height_m ** 2)
    
    # Determine health category based on BMI score
    if bmi < 18.5:
        category = "Underweight"
    elif 18.5 <= bmi < 25.0:
        category = "Normal weight"
    elif 25.0 <= bmi < 30.0:
        category = "Overweight"
    else:
        category = "Obesity"
        
    # Return both the rounded score and the text category
    return round(bmi, 2), category

# User inputs
user_weight = 70  # in kg
user_height = 1.75 # in meters

# Call function and capture returned values
bmi_score, bmi_category = calculate_bmi(user_weight, user_height)

print(f"Your BMI is {bmi_score}, which is classified as: {bmi_category}.")
# Output: Your BMI is 22.86, which is classified as: Normal weight.

7. Common Beginner Mistakes

⚠️ Watch out for these mistakes:

  • Unreachable Code After Return: Any code written below a return statement inside the same block will never run.
  • Forgetting the return Keyword: If you perform calculations in a function but forget to write return, calling the function returns None.
  • Printing a Function That Uses print(): Writing print(my_function()) when my_function() already uses print() instead of return will display your output followed by an unexpected None.

8. Code Examples

Here are a few common patterns involving return values in Python:

# 1. Returning a Boolean value directly
def is_even(number):
    return number % 2 == 0

print(is_even(4))  # Output: True
print(is_even(7))  # Output: False

# 2. Returning None explicitly when no action is taken
def find_first_negative(numbers):
    for num in numbers:
        if num < 0:
            return num
    return None  # Executed only if no negative number was found

print(find_first_negative([3, 5, -2, 8]))  # Output: -2
print(find_first_negative([1, 2, 3]))      # Output: None
Interactive Practice

Mini Practice: Temperature Converter

Write a function named celsius_to_fahrenheit(celsius) that accepts a temperature in Celsius, converts it using the formula (celsius * 9/5) + 32, and returns the result. Call the function with 25, store the output in a variable named temp_f, and print temp_f.

0% complete
Check when done
Quiz

Test Your Understanding

1. What value is returned by default if a Python function does NOT contain an explicit `return` statement?

2. What happens to any code placed immediately AFTER a `return` statement in the same execution path?

3. What is the output of the following code?

def show_sum(a, b):
    print(a + b)

result = show_sum(2, 3)
print(result)

4. How does Python handle returning multiple values like `return x, y, z`?

9. Challenge Project

E-Commerce Order Processor: Build a function named process_order(price, quantity, discount_code). The function should calculate the subtotal (price * quantity). If discount_code is "SAVE10", apply a 10% discount. If discount_code is "SAVE20", apply a 20% discount. Finally, calculate 5% sales tax on the discounted total. return three values: subtotal, discount_amount, and final_total. Call your function with sample order data and print an itemized receipt summary!

10. Key Takeaways

  • Use return to send output data back to the code that called the function.
  • print() is for human inspection; return is for code execution and data manipulation.
  • Functions exit immediately once a return statement is reached.
  • You can return multiple values separated by commas, which Python returns as a tuple.
  • If a function ends without encountering a return statement, it returns None.

🚀 Progression

You've mastered arguments and return statements. Now it's time to understand where your variables live in the upcoming lesson on **Variable Scope**!