What are Python Functions? Explained For Beginners

What are Python Functions? Explained For Beginners thumbnail

If you've written a "Hello World" program in Python, then you've seen this before:

print("Hello World")

Behind the scenes, the print keyword represents several lines of code you don't see, and this is what actually tells the computer to display your text on the Python console.

In Python, functions are a way to group code or a set of statements that can be reused or executed as many times as needed in a program. They are sometimes referred to as a method or procedure.

Python functions are usually referenced by a name, and when this is the case, the set of statements can be reused or executed as many times as needed in a program. It is a way to run the same statements from multiple places in a program without having to rewrite them each time they are needed.

In Python, functions are first-class citizens. This means that you can pass functions around like any other object, assign them to variables, store them in lists and tuples, or define them inside other functions. Python already comes with pre-defined functions like print(). These predefined functions are known as built-in functions, and Python allows you to create your functions called user-defined functions.

This article addresses the following touchpoints:

  • How to define functions in Python
  • Function parameters and arguments
  • Return values
  • How to call Python functions
  • Python Lambda functions
  • Variable scope

If you've not set up Python locally and would like to run the examples used in this article, you can use an online interpreter like OnlineGDB Python Interpreter.

How to define functions in Python

A way to define a function in Python is by using the def keyword. Let's write a function that accepts two numbers and returns their sum as a new value:

def sum(value1, value2):
  """This sums two values"""
  sum_of_values = value1 + value2
  return sum_of_values

From our above function:

  • The function name is provided right after the def keyword.
  • The parenthesis holds the' function parameters' right after the function name.
  • The code block indented from the next line (after the colon) is the function body.
  • The first statement in the function body is the function's documentation string (docstring) and is optional.
  • The return statement is used to end the execution of a function while returning a specified value. This value is called the return value.

Function parameters

The parameters of a function are names used to represent real values that are provided when a function is called. In our example above, the function parameters are value1 and value2. When we call the sum function, we'll provide the values for these parameters.

What is a function call?

A function call is a request to execute a function. To call our function, we'll write its name followed by a parenthesis. Let's assign our function call to a variable in our next block. This means that the value of our variable will be equal to our function's return value:

result = sum()
print(result)

Here's what we'll see on our terminal when we run the above code:

TypeError: sum() missing 2 required positional arguments: 'value1' and 'value2'

Remember that in our function definition, we used two parameters, value1 and value2, to represent the real values to be summed. To provide the values that we want to be summed, we'll place them right inside the parenthesis in our function call. The values we provide during our function call are called function arguments.

result = sum(5, 6)
print(result)

Result:

11

Our function can return different outputs based on predefined conditions in its definition. For instance, if we would like to work with only small numbers, we can choose to return a different output if both numbers, when summed, would be greater than 100:

def sum(value1, value2):
  sum_of_values = value1 + value2
  if (sum_of_values > 100):
    return "Too big!"
  return sum_of_values

result = sum(90, 32)
print(result)

Result:

Too big!

During a function definition, the names that represent the values we intend to supply to the function are called function parameters. The actual values provided to the function during a function call are called function arguments.

The return keyword

The return keyword is used to end the execution of a function while returning a specified value.

If we don't use the return keyword to tell our function what to return, its default value will be None. Let's test this by creating a function without a return statement and then calling it:

def sum(value1, value2):
  sum_of_values = value1 + value2

print(sum(5, 9))

Result:

None

The function also returns None by default when the return keyword is provided without a value. This makes it an empty return:

def sum(value1, value2):
  sum_of_values = value1 + value2
  return

print(sum(5, 9))

Result:

None

Function arguments

Function arguments are the values that are provided to the function when it is called. These values will be used to replace the function parameters during the function call. Let's learn about the different types of function arguments:

Positional arguments

By default, function arguments in Python are `positional arguments. This means that the values have to be ordered the same way they were supplied during the function definition:

def sum(value1, value2):
  print("This is value2: " + str(value2))
  print("This is value1: " + str(value1))

print(sum(90, 32))

Result:

This is a value2: 32
This is a value1: 90
None

Keyword arguments

Keyword arguments are an alternative to positional arguments. When we use keyword arguments in a function call, Python determines what parameter it represents through the parameter name used in the function definition. In this way, we can place our arguments out of order:

def sum(value1, value2):
  print("This is value2: " + str(value2))
  print("This is value1: " + str(value1))

print(sum(value2 = 32, value1=90))

Result:

This is a value2: 32
This is a value1: 90
None

Required arguments

As we saw earlier, the arguments are required by default. This means that Python will throw an error if the number of parameters provided in the function definition is not the same as the number of arguments supplied in the function call:

def sum(value1, value2):
  sum_of_values = value1 + value2
  return sum_of_values

result = sum(90)
print(result)

Result:

TypeError: sum() missing 1 required positional argument: 'value2'

Default arguments

To make an argument optional in a function call, we have to give it a default value in our function definition. This default value will be used if no argument for that parameter is supplied during the function call:

def sum(value1, value2=10):
  sum_of_values = value1 + value2
  return sum_of_valueshis

result = sum(90)
print(result)

Result:

100

Arbitrary Arguments

When the exact number of arguments to be supplied during our function call is not known, we can use arbitrary arguments. We add an asterisk (*) to use arbitrary arguments before the parameter name in our function definition. This will make the parameter a tuple and our function will receive a tuple of arguments for every argument supplied in place of the parameter during our function call:

def sum_all(*values):
  print("A tuple of all the arguments:", values)
  sum_of_all_values = sum(values)
  return sum_of_all_values

result = sum_all(4, 7, 13, 45)
print("The sum of all supplied arguments:", result)

Result:

A tuple of all the arguments: (4, 7, 13, 45)
The sum of all supplied arguments: 69

Python Lambda functions

Another way to define functions in Python is by using the lambda keyword. This method of function-definition is mostly used to create anonymous functions, functions that have no name, hence the word anonymous. By syntax, lambda functions can have multiple arguments but are restricted to only one expression. Let's redefine our sum() function using the lambda keyword:

lambda value1, value2: value1 + value2

A few things to note:

  • Our function definition does not have a return statement. The expression after the column (:) is by default, the return value.
  • There is no way to reuse our function since it can't be referenced by a name.

You'll find Lambda functions useful when you need to pass a function as an argument to higher-order functions. Higher-order functions are functions that operate on other functions, either by taking a function as its argument or returning a function. The map() is an example of a higher-order function. In Python, the map function takes a function and a list as arguments. This is one case where we don't need our function to be reusable, hence, the need for a lambda function. Let's use the map() and lambda functions to return half of every number in a list:

list_of_numbers = [19, 12, 45, 72, 10]
halved_list = list(map(lambda value: value/2 , list_of_numbers))

print(halved_list)

Result:

halved list: [9.5, 6.0, 22.5, 36.0, 5.0]

To be able to reuse a lambda function, we can assign it to a variable:

sum = lambda value1, value2: value1 + value2
result = sum(7, 9)

print(result)

Result:

16

Variable scope

Variables that are defined inside a function body are locally scoped. This means that they can only be accessed inside the function definition:

def example_function():
  word = "inevitable" # the word variable is locally scoped
  return word

print(word)

Result:

NameError: name 'word' is not defined

Notice that our print() statement is outside our function-defintion. As this is outside the scope of our function body, the word variable is not accessible to statements or expressions that are outside our function definition.

To make our word variable accessible to every statement and expression in our code, we have to declare it outside the function definition. In this way, it is globally scoped:

word = "inevitable" # the word variable is globally scoped
def example_function():
  return word

print(word)

Result:

inevitable

Important things to note

When defining a function using the def keyword, after the function name and colon, the function-body should be indented from the next line.

Notice how we indented our function body in def function definitions. This is a way to tell Python that everything we are about to write next belongs to our function definition. If your function body is not indented, Python will assume that you've begun a different statement:

def sum(value1, value2):
sum_of_values = value1 + value2
return sum_of_values

result = sum(3, 7)
print(result)

Result:

IndentationError: expected an indented block

A function name should be descriptive, straight to the point and timeless.

You wouldn't want to be addressed by a different name, would you? It's the same thing with functions. Name them after what they do and represent.

Notice how we named our first function sum. This is because its job is to sum values. Doing this would help anyone know what our function does by just looking at its name.

Function naming is a very important part of function definition and, when done properly, will make your code more readable and maintainable and further increase productivity.

When naming your functions, it is important to not use slangs that only a few people would understand or trends that people can only relate to at a given time. Let your function names be descriptive enough, straight to the point and timeless.

A function should have only one responsibility.

When you define your function, it is good practice to give it just one responsibility and make it do what its name suggests. This means that from our examples, choosing to sum two numbers while dividing every number in another tuple by two all in the same function would not be a good idea. Like we did, splitting the two actions into separate functions is better.

By doing this, you would not only improve your code readability, but you'll also make it easier to test and debug.

Summary

  • A function is a set of statements designed to perform a particular task.
  • During a function definition, the names that represent the values we intend to supply to the function are called parameters.
  • During a function call, the actual values provided to the function are called arguments.
  • The return statement is used to end the execution of a function while returning a specified value.
  • Variables that are defined inside a function body are locally scoped. This means that they can only be accessed inside the function definition.
  • An anonymous function is a function that has no name.
  • To define an anonymous function, we use the lambda keyword, and to reuse an anonymous function, we have to assign it to a variable.
  • Function names should be descriptive, straight to the point and timeless.
  • It is good practice to give your function just one responsibility.

Thanks for reading! If you still have trouble understanding the concept of functions, no worries; here's a link to The Simplest Explanation of Functions You’ll Ever Read.

Found this helpful? Please like 💓 and share this post! 🎷

user profile
See more articles
share link icon