Return Statements in Python- A Complete Guide

What Return Statements Actually Do in Python

A return statement ends a function's execution and sends a value back to wherever the function was called. That's it. No magic, no ceremony.

If you've been using print() when you should have used return, your code is probably broken and you don't even know it yet.

Return vs Print: The Difference That Matters

This trips up beginners constantly. print() displays output to the console. return sends a value back to the program.

See the difference:

def with_print(x):
    x * 2

def with_return(x):
    return x * 2

result1 = with_print(5)
result2 = with_return(5)

print(result1)  # None
print(result2)  # 10

The with_print function does the calculation but throws it away. result1 is None because nothing gets sent back.

Returning Nothing: When None Makes Sense

Functions without an explicit return statement return None automatically. This is fine when your function performs an action rather than producing a value.

def log_message(msg):
    print(f"[LOG] {msg}")
    # implicitly returns None

This function's job is side effects—logging, not calculating. Returning None is correct here.

Multiple Return Values: Python's Tuple Trick

Python functions can return multiple values. They're actually returning a tuple.

def get_stats(numbers):
    return min(numbers), max(numbers), sum(numbers)

low, high, total = get_stats([1, 2, 3, 4, 5])
print(low, high, total)  # 1 5 15

This is clean syntax for a common pattern. No dictionaries or custom objects needed.

Early Returns: Exiting Functions Prematurely

You can return from anywhere inside a function. This is useful for guard clauses—checking conditions and bailing out early.

def divide(a, b):
    if b == 0:
        return "Cannot divide by zero"
    return a / b

Instead of nested if-else blocks, you check the problem case first and return immediately. Your code stays flat and readable.

Returning Functions: Closures and Decorators

Functions can return other functions. This enables closures and decorators—advanced patterns you'll encounter in real code.

def multiplier(factor):
    def inner(number):
        return number * factor
    return inner

double = multiplier(2)
print(double(5))  # 10
print(double(10))  # 20

multiplier returns the inner function, which remembers the factor value. This is closures in action.

Common Mistakes to Avoid

The Return Statement Comparison Table

Statement Behavior Use When
return value Sends value back, exits function Function produces a result
return (bare) Returns None, exits function Early exit, no value needed
No return statement Returns None implicitly Side-effect-only functions
return a, b, c Returns tuple (a, b, c) Multiple related values

How to Start Using Return Statements Correctly

  1. Identify the function's purpose. Does it compute something or just perform an action?
  2. If it computes: use return result to send the value back
  3. If it performs an action: use print() or modify data in place, return None
  4. Test your function. Assign the function call to a variable and print it
# Wrong approach
def calculate_tax(price, rate):
    price * rate / 100  # Result disappears

# Correct approach
def calculate_tax(price, rate):
    return price * rate / 100

tax = calculate_tax(100, 20)
print(tax)  # 20.0

Return Statements and Generator Functions

Generator functions use yield instead of return. When a generator is exhausted, it raises StopIteration—the return value becomes the exception's value if you catch it.

def count_to_three():
    yield 1
    yield 2
    yield 3
    return "done"

gen = count_to_three()
for item in gen:
    print(item)

Most of the time you won't need the return value of generators. But it's there if you do.

When Return Values Get Ignored

Python doesn't force you to use a return value. This is valid:

def add(a, b):
    return a + b

add(2, 3)  # Return value thrown away

This is fine for functions with side effects, but wasteful if the function does actual computation. You're burning CPU cycles for nothing.

Bottom Line

Return statements transfer computed values out of functions. Use them when your function produces something. Don't use print() as a substitute—it's for humans reading output, not for programs getting data.

Get this distinction right early. It eliminates an entire category of bugs from your code.