6  Functions

Warning

Any changes you make to the code on this page, including your solutions to exercises, are temporary. If you leave or reload the page, all changes will be lost. If you would like to keep your work, copy and paste your code into a separate file or editor where it can be saved permanently.

6.1 Functions

When we need to perform the same task multiple times in a program, it is a bad idea to copy and paste the same code again and again. Instead, we can define a function and write the code once, and call the function whenever we need it.

Functions help us break programs into smaller and reusable parts. This makes programs easier to read, modify and also easier to test (for example, we can check functions using sets of prepared input and expected output). Because they are reusable, we can also use functions that others have developed and grouped in packages that we can import, which speeds up development.

The general syntax of a function is:

def function_name(parameters):
    # Function body (indented code block)
    # Optionally returning a result

Function names follow the same rules as variable names. They are preferably verbs and should be descriptive so that the purpose of the function is clear.

The parameters are a comma-separated list of variable names. These variables, and any other defined inside the function, are called local variables, and they are accessible only from within the function. They exist only while the function is running.

To return a value from a function (and exit it), we use the return statement:

    return value

If the function does not contain a return statement, it returns None (the only possible value of the NoneType), indicating “no value”.

Examples. The first example is a simple function to print a welcome message. The function has no parameters and does not include any explicit return statement:

Since greet has no return statement, it implicitly returns None. We can verify that by printing its result:

Here, the first line in the output is the text printed inside greet. The None on the second line is the function’s return value.

If we want to include a name in the output and specify it when we call the function, we can define the function with a parameter:

The next example defines a function calculate_bmi that has two parameters, weight_kg and height_cm and returns the body mass index (BMI):

A function can also contain multiple return statements. The first one reached will stop the function and provide the value to be returned.

6.1.1 Non-default and default parameters

We can also define default values for function parameters. These default values are used when no value is given in the function call. When defining a function, all parameters without a default value (non-default parameters) must be listed before those with default values (default parameters).

Exercise. Look at the example below (without running the code). What do you expect the following program to print? After you decide, run it and check if you were correct.

%%explain
def function():
    variable = 2
    return variable

variable = 1
function()
print(variable)
1def function():
2    variable = 2
3    return variable
4
5variable = 1
6function()
7print(variable)

Main program (before executing line 1)

No variables

Main program (before executing line 5)

function:
<function>
function at 0x1064993a0

Main program (before executing line 6)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

Main program (executing line 6)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

function (entering function at line 1)

No variables

Main program (executing line 6)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

function (before executing line 2)

No variables

Main program (executing line 6)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

function (before executing line 3)

variable:
2
int at 0x100d524f8

Main program (executing line 6)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

function (leaving the function after executing line 3)

variable:
2
int at 0x100d524f8
(returning):
2
int at 0x100d524f8

Main program (before executing line 7)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8

Main program (program ended after executing line 7)

function:
<function>
function at 0x1064993a0
variable:
1
int at 0x100d524d8


The program prints 1. The variable defined inside the function is a local variable and has nothing to do with the variable defined in the main program.

Note for beginners. In the first chapter we compared functions to asking a friend for a favor. Now think of variables as notes written on a sheet of paper. Each note is a piece of data (a value) with a label (a variable name).

When you ask a friend (call a function), you hand them their own sheet of paper with the information they need. This sheet contains the labels (parameter names) they understand, and the values you give them (the arguments). While working, your friend may add more notes to their own sheet. Even if they use the same labels as you do on your sheet, these are completely separate. You cannot see your friend’s notes, and your friend cannot see yours.

When your friend is done, they hand back a single result (the return value) on a new sheet of paper without any label. They also throw away the sheet you gave them. After you receive the sheet from your friend, you can decide what you want to do with the value on it, for example, copy it onto your own sheet under a new label.

Exercise. Write and test a function to count the number of positive numbers in a list (you can assume that it contains only numbers):

Sample solution

6.2 Lambda functions

Python also supports anonymous functions, also known as lambda functions. These are short functions that do not need a name, and consist of a single expression, which is evaluated and returned:

lambda parameters: expression

For example, the following anonymous function has one parameter and returns its value plus one:

lambda a: a + 1

Here is another one with two parameters, returning their product:

lambda a, b: a * b

Note that there are no parentheses around the parameters and that we have not used the return keyword.

Lambda functions are often useful when we want to pass a function as an argument. The next example shows how to calculate the first 10 powers of 2 in a single line:

The map function applies the function given as the first argument to each element of an iterable given as the second element.

We could also have defined a (named) function first and then use it in map:

The lambda function allowed us to do the same without creating a named function, making the code shorter and more concise.

A small note on using a list in the example: Without it, map returns a map object, which can produce (or yield) elements one by one, but does not do so automatically (it is lazy). Wrapping it in list forces all elements to be retrieved at once and collected into a list.