WasiLearn Code
Python · Getting started

return: getting an answer back

Every function you wrote in the last lesson printed something. None of them gave you anything. That difference is small to write and large to understand, and it catches nearly everyone.

The problem

Here is a function that looks finished:

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

total = add(2, 3)
print(total)
output
5
None

The 5 came from inside the function. Then print(total) printed None — Python's word for "no value at all", which you met when append handed nothing back in the lists lesson.

add put a number on the screen and gave nothing to the program. total holds that nothing.

return

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

total = add(2, 3)
print(total)
output
5

One word changed and the function now hands a value back to whoever called it. add(2, 3) does not print 5 — it becomes 5, and can be used anywhere a 5 could be used:

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

print(add(2, 3))
print(add(2, 3) * 10)

scores = [add(1, 1), add(2, 2)]
print(scores)
output
5
50
[2, 4]

None of that is possible with a function that only prints.

print is for people, return is for programs

That is the whole rule, and it is worth memorising:

  • print puts characters on a screen. A human reads them. The program cannot.
  • return hands a value back into the program. Code can use it. Nobody sees it unless you print it.

A function that only prints is a dead end — it can never be part of a bigger calculation.

return stops the function immediately

Nothing after a return runs:

def check(age):
    if age >= 18:
        return "adult"
    return "minor"

print(check(20))
print(check(11))
output
adult
minor

Follow check(11): 11 >= 18 is False, so the if block is skipped and the last line runs. Follow check(20): the condition is True, return "adult" runs, and the function ends right there — the final line never happens. That is why no else is needed.

Useful, and also a trap:

def total(scores):
    running = 0
    for score in scores:
        running += score
        return running
    return running

print(total([1, 2, 3]))
output
1

The return is inside the loop, so the function ends on the very first pass. Expected 6, got 1. When a loop seems to run only once, check the indentation of your return.

def total(scores):
    running = 0
    for score in scores:
        running += score
    return running

print(total([1, 2, 3]))
output
6

Same lines, one moved out a level.

Returning other things

Anything can be returned — a string, a list, a dictionary, a True or False:

def is_pass(score):
    return score >= 50

def grade(score):
    if score >= 80:
        return "A"
    elif score >= 65:
        return "B"
    return "C"

print(is_pass(72))
print(grade(72))
output
True
B

A function returning True or False reads beautifully inside an if, because the call is the condition:

def is_pass(score):
    return score >= 50

for score in [82, 45, 60]:
    if is_pass(score):
        print(f"{score}: pass")
    else:
        print(f"{score}: fail")
output
82: pass
45: fail
60: pass

Notice there is no if is_pass(score) == True. is_pass(score) is already True or False; comparing it to True adds nothing.

Building things out of small functions

Once functions return values, they combine:

def average(scores):
    return sum(scores) / len(scores)

def grade(score):
    if score >= 80:
        return "A"
    elif score >= 65:
        return "B"
    return "C"

marks = [88, 76, 91]
print(average(marks))
print(grade(average(marks)))
output
85.0
A

grade(average(marks)) — the inside runs first, and its answer goes straight into the outside. Each function does one small job and knows nothing about the other. That is what people mean when they say code is well designed, and it starts with return.

Prefer learning with a teacher?

WasiLearn Academy runs small-group classes covering this material, online and in Karachi.

See the classes