Lesson 3 of 3
Use return to send results back, return several values at once, understand None, and see how variables inside functions are kept separate.
About 25 minutes
return inside conditions to exit earlyBeginners often mix up print() and return, because both seem to produce a result. They do very different things. print() displays text for a person to read and then the value is gone. return hands a value back to the code that called the function, so the program can keep working with it.
def kelvin_printed(temperature_c): print(temperature_c + 273.15)def kelvin_returned(temperature_c): return temperature_c + 273.15result = kelvin_returned(25)print(result * 2)result = kelvin_printed(25)print(result)The second function prints 298.15, but its result can't be used: the variable result receives None. A function without a `return` statement returns `None`, Python's value for nothing. As a rule, have functions return results and let the main part of the program decide what to print.
A function call that returns a value can go anywhere a value can: in a calculation, in an f-string, in a condition, as an argument to another function, or in a list.
def density(mass_g, volume_cm3): return mass_g / volume_cm3samples = {"A": (27.0, 10.0), "B": (89.6, 10.0), "C": (45.1, 10.0)}for name, (mass, volume) in samples.items(): rho = density(mass, volume) label = "light" if rho < 5 else "heavy" print(f"Sample {name}: {rho:.2f} g/cm³ ({label})")"light" if rho < 5 else "heavy" is a conditional expression: a one-line if/else that produces a value. The loop also unpacks each (mass, volume) tuple directly in the for line.
A function can return several values by separating them with commas. Python packs them into a tuple, which the caller can unpack into separate variables, exactly as in the Tuples lesson.
A function that summarises a set of hardness measurements.
def summarise(values): mean = sum(values) / len(values) return min(values), max(values), meanlow, high, mean = summarise([152, 160, 158, 149, 155])print(f"Hardness: {low} to {high} HV, mean {mean:.1f} HV")return ends the function straight away. Combined with if, this lets a function deal with special cases first and then get on with the normal calculation, which often reads more clearly than deep nesting.
def classify(band_gap_ev): if band_gap_ev < 0: return "invalid" if band_gap_ev == 0: return "conductor" if band_gap_ev < 3: return "semiconductor" return "insulator"for gap in [0, 1.12, 5.5, -1]: print(gap, classify(gap))Variables created inside a function, including its parameters, are local: they exist only while the function runs and can't be seen from outside. Each call starts fresh. Variables created in the main part of the program are global: functions can read them, but should normally receive what they need through parameters instead.
def kinetic_energy(mass, velocity): energy = 0.5 * mass * velocity ** 2 # energy is local return energyresult = kinetic_energy(2.0, 3.0)print(result)print(energy) # NameError: energy only existed inside the functionThe first print() works; the second raises NameError: name 'energy' is not defined. The returned value is the only thing that leaves the function, which is exactly why return matters.
Keep functions self-contained
return is easy to test, reuse and understand. Avoid functions that quietly depend on, or change, global variables.Choose an answer and press Check answer. You can retry as often as you like.