LambdaLabTM
Computer Science · Class 12 · Functions
Functionsreturn⏱️ 14 min read

Returning Value(s)

return does two things at once, and both matter. It hands a value back to whoever called the function, and it ends the function immediately — nothing after it runs. The bracket in the title is the third thing: one return can hand back more than one value.

1Handing a value back

return_one.py
def square(n):
    return n * n

print(square(7))
result = square(9)
print(result + 1)
Output
49
82

The call square(7) does not just run the function — it becomes the value 49. That is why it can be printed, stored in result, and added to. A call to a returning function is an expression, and you can use it anywhere an expression is allowed.

2Catch what comes back, or it is gone

A returning function hands the answer to whoever called it. It does not print it, and it does not store it anywhere. If the call is written on a line of its own, there is nobody holding the answer — so Python throws it away.

lost_or_kept.py
def area(length, breadth):
    return length * breadth

area(4, 5)                      # 20 is worked out... and dropped

area_of_rect = area(4, 5)       # 20 is caught in a variable
print(area_of_rect)
Output
20

Only one line of output, from the print. The first call ran the whole function and produced 20 exactly as the second one did — it just had nowhere to put it.

Watch Out
This is not an error, and that is what makes it dangerous. Python does not warn you that a returned value went unused. The program runs, nothing is printed, and it looks as though the function did not work. In an exam this is the difference between a mark and no mark, and the cause is one missing name = at the front of the line.

“Catching” does not have to mean a variable. It means using the value for something — any of these three will do:

Store it
area_of_rect = area(4, 5)

Keep it under a name so later lines can use it. The usual choice.

Print it
print(area(4, 5))

Hand it straight to print. The value is used, just not kept.

Use it in an expression
total = area(4, 5) + area(2, 3)

The call becomes its value, so it can be added, compared or passed on.

3return ends the function on the spot

return_ends.py
def check(n):
    if n < 0:
        return 'negative'
    print('this line runs only for 0 and above')
    return 'zero or positive'

print(check(-5))
print(check(4))
Output
negative
this line runs only for 0 and above
zero or positive
return 'negative'

For -5 this runs, and the function is finished. The print below it never happens — which is why the first call produced only one line of output.

print('this line runs only for 0 and above')

Reached only when the if was false, because otherwise the return above has already left the function.

Key Takeaway
return is an exit, not just a hand-over. It is like break for a whole function. That makes it useful for stopping early — and it is why code written after a return at the same indentation can never run.

4A function with no return gives back None

no_return.py
def show(n):
    print(n)

x = show(5)
print(x)
print(type(x))
Output
5
None
<class 'NoneType'>

Every call produces a value. A function that never says return produces None, which is Python's word for “nothing”. The 5 you see was printed by the function; the None is what the function gave back.

So the mistake of the last section has a mirror image. There, a value came back and nobody caught it. Here, somebody catches — and nothing was sent:

nothing_to_catch.py
def show_area(length, breadth):
    print(length * breadth)      # prints; does not return

show_area(4, 5)                  # right: just call it

answer = show_area(4, 5)         # wrong: there is nothing to catch
print(answer)
print(answer + 1)
Output
20
20
None
Traceback (most recent call last):
  File "nothing_to_catch.py", line 8, in <module>
    print(answer + 1)
          ~~~~~~~^~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

The assignment itself is not an error — answer is quite happily set to None. The trouble comes one line later, when you try to use it as a number.

Key Takeaway
Match the call to the shape of the function. If it returns, catch the value — store it, print it, or use it in an expression — or the answer is wasted. If it only prints, call it on a line of its own and do not put a name = in front, because the only thing you would be storing is None.
Returns a value → catch it
def area(l, b): return l * b a = area(4, 5)

Writing area(4, 5) alone is legal and silent, and the 20 is lost.

Only prints → call it bare
def show(l, b): print(l * b) show(4, 5)

Writing a = show(4, 5) is legal too, and puts None into a.

A bare return with nothing after it does the same, and is used to leave a function early:

bare_return.py
def maybe(n):
    if n < 0:
        return                # leave now, hand back nothing
    print('n is', n)

print(maybe(-1))
maybe(3)
Output
None
n is 3

5Returning several values at once

Put commas between them. The function hands back a tuple, and the caller can take it apart into separate names:

return_many.py
def stats(numbers):
    return min(numbers), max(numbers), sum(numbers) / len(numbers)

print(stats([4, 9, 1, 7]))

lowest, highest, average = stats([4, 9, 1, 7])
print('lowest :', lowest)
print('highest:', highest)
print('average:', average)
Output
(1, 9, 5.25)
lowest : 1
highest: 9
average: 5.25
Key Takeaway
There is no new feature here. return a, b, c is the packing you met in Class 11 — commas on the right build a tuple — and lowest, highest, average = stats(...) is the unpacking that takes it apart. Python has exactly one return value; it is just that one tuple can hold three things.
return_type.py
def stats(numbers):
    return min(numbers), max(numbers)

print(type(stats([1, 2, 3])))
Output
<class 'tuple'>
Watch Out
The number of names must match. Three values into two names raises ValueError: too many values to unpack (expected 2) — the same error, from the same cause, as unpacking any other tuple.

6A function can return anything

A number, a string, a Boolean, a list, a dictionary — whatever suits the job:

return_list.py
def evens(numbers):
    out = []
    for n in numbers:
        if n % 2 == 0:
            out.append(n)
    return out

print(evens([1, 2, 3, 4, 5, 6]))
Output
[2, 4, 6]

A function returning True or False is especially worth having, because it drops straight into a condition:

return_bool.py
def is_pass(mark):
    return mark >= 33

if is_pass(45):
    print('Passed')

print(is_pass(20))
Output
Passed
False
stats.py

7Recap

return hands a value back

The call becomes that value, so it can be stored, printed, added or compared.

return also ends the function

Like break for a whole function. Lines after it, at the same level, can never run.

No return means None

Every call produces something; a function that never returns produces None, and None cannot be used in arithmetic.

Commas return a tuple

return a, b, c is packing; lowest, highest, average = f() is unpacking. One return value that happens to hold three.

✍️ Now write these yourself
  1. 1

    Write cube(n) that returns the cube, and print the sum of two cubes.

    Hint · cube(2) + cube(3) is 35. This only works because the function returns.

  2. 2

    Write a function that returns both the quotient and the remainder of two numbers.

    Hint · return a // b, a % b, then unpack into two names.

  3. 3

    Write is_even(n) returning a Boolean and use it inside an if.

    Hint · return n % 2 == 0. No if needed inside the function — the comparison is already True or False.

  4. 4

    Write a function that returns early for a negative input, and check what it hands back.

    Hint · A bare return gives None. Print the call to see it.

  5. 5

    Return three values and try to unpack them into two names.

    Hint · ValueError: too many values to unpack (expected 2) — the same error as with any tuple.

Quick Check

What does `x = show(5)` put into x, if show only prints?

Quick Check

In `def check(n)`, why does check(-5) print only one line?

Quick Check

What type does `return min(n), max(n)` hand back?