Functions are an important part of Python and are used to define blocks of code that can be reused at a later point in the program using the name. Each function consists of the following components:
def
– Keyword: Every function definition begins with this keyword followed by a unique name for the function. The naming rules for functions are identical to those for variables, so the function name cannot begin with a number and must not contain any special characters.- Parameters & arguments: These are variables that are passed to the function when it is called. They can be used to perform calculations or make other changes within the function. The arguments, on the other hand, are the actual values that the function receives when it is called. The parameters are defined in round brackets and separated by commas. The first line of a function ends with a colon after the definition of the parameters.
- Indentation: As already described, indentation plays an important role in Python and indicates which sections of code belong together. The line with the keyword def is followed by an indentation that continues to the end of the function and thus indicates when the function ends.
- Return values: To return the calculations that take place within a function to the rest of the program, so-called return values are used, which are preceded by a
return
. However, these return values do not have to be defined. A function can also end without areturn
. However, it is important to note that the execution of the code always stops afterreturn
and the subsequent code with indentation is no longer taken into account.
What are the different types of arguments and how can they be used?
When a function is called, the parameters allow different values to be passed to it, which can then be used for further calculation. This forms the main core of functions, as it allows a standardized code block to be called several times and return the corresponding results.
There are different types of arguments that can be used:
Positional arguments are determined by the position in the function call. The position therefore plays a decisive role, as it is compared with the function definition. This means that a call with the same arguments at different positions can also lead to different results.
Keyword arguments, on the other hand, can be identified using parameter names in the function call. This also makes the code easier to understand, as it explicitly specifies which argument is passed for which parameter. This detail means that the order of the arguments no longer plays a role.
Default parameters can be used to store default values that are used if no explicit argument for this parameter was specified in the function call. However, if an argument is passed, the default value is not used.
In some cases, it can be useful for the parameters not to be defined from the outset, but to be defined when the function is called and can change each time the function is called. For such cases, Python uses *args
to pass any number of positional arguments and **kwargs
to pass any number of keyword arguments.
How to return values from a function?
The main goal of functions is to create reusable blocks of code that can be called at different times during program execution and can return different results depending on the arguments. The return
keyword is used so that the result of the function can be returned to the program. This allows the result of the function to be saved in a variable and reused in the program.
A function can also return more than one value. However, this must be taken into account when calling the function so that sufficient variables are made available to store the results. If this is not the case, the program throws an error.
When working with the return
statement, however, it is important to know that it causes the function to terminate at exactly this point. If it is called too early, the subsequent code is no longer executed. This behavior can quickly lead to confusion in loops, for example. You should therefore make sure to place the return at the correct point.
Only the second function returns the correct result, as the first function terminates after one iteration because the return
statement is used within the for
loop.
What are the different lifetimes and scopes of variables in functions?
In the context of functions and variables, the scope of variables must be taken into account. Variables that are defined within a function are only valid within this function. These so-called local variables are not even recognized outside the function, as this is outside their scope of validity.
The situation is different with global variables that are defined outside the function. This is also part of the scope of the function and is recognized within the function and calculations can be continued with this variable.
However, to be able to make changes to this variable or overwrite its value, the keyword global
must first be used together with the variable to adjust the scope so that the changes are also valid outside the function.
What are functions that are already built into Python?
Python has a large number of standardized functions that are already stored in such a way that they can be used without further ado. The most important built-in functions in Python are
print()
: This function prints the arguments inside the brackets in the console or the Jupyter notebook. The following program blocks are still executed. Several arguments can also be passed, which are then combined in the appropriate order and separated by a space.len()
: This function returns the length of various data structures. It can be used, for example, to output the number of characters in a string.type()
: This call can be used to return the data type of a variable.range()
: The range function returns a sequence of numbers specifying a start point and an end point. The end point is not part of the sequence.
What is Recursion?
Recursion is a programming technique in which a function can call itself. In Python, this can be implemented by a function simply calling itself within the definition. The call creates a new instance that is independent of the calling instance and therefore has its own variables.
This technique can be used to perform recursive calculations, which are required for the factorial, for example. The factorial is defined as the product of the integer with the factorial of the previous integer. This can be implemented in Python as follows.
The recursion process distinguishes between two cases:
- Base case: The base case comprises the condition at which the recursion stops, the function stops calling itself and returns a result. In the example shown, the base case is reached when
n
has assumed the value zero. - Recursive case: The recursive case is the condition under which the function continues to call itself in order to perform a partial calculation. In the case of the factorial, the recursive case is reached as long as
n
is not equal to zero, as the factorial of the smaller number must then still be calculated.
What are higher-order functions?
Python functions of higher order are characterized by the fact that they use whole functions as input variables. Up to this point, however, we had only dealt with functions that use individual values or possibly lists as input. With the help of this concept, powerful applications can be created in Python that are able to apply a function to different objects one after the other.
In Python, there are standard higher-order functions that are used in many programs. The most common are
map()
uses a specific function to apply it to all elements in an iterable, such as a list or a tuple. As a result, it returns the same iterable with the results from the applied function. In our example,map()
uses thesquare()
function as the first argument and executes it on a list of numbers. The result is a new list in which each previous element has been squared accordingly:
filter()
uses a function as input to determine the logic to be used for filtering. Analogous tomap()
, an iterable whose elements are to be filtered accordingly is used as the second argument. In our example, only the elements that are even, i.e. divisible by two, should be included. The filter logic is stored in theis_even()
function and passed tofilter()
as the first argument. The list numbers then contains all the numbers that are to be filtered, leaving only the two and the four.
reduce()
offers the option of performing a calculation with all elements of the iterable. This allows all elements to be multiplied or added together, for example. As a result,reduce()
does not return an iterable, but a single value. In our example, we calculate the product of all elements that are stored in the numbers list. The logic of the multiplication is stored in themultiply
function.
Higher-order functions provide a powerful tool by allowing entire functions to be used as input parameters for another function. This also allows individual code blocks to be reused efficiently, making the code clearer.
What are lambda functions?
The lambda functions in Python are so-called anonymous functions, as no explicit name is required for the definition. Instead, a functioning function can be defined within one line using the keyword lambda
. Because of this keyword, the functions are often just called lambdas or lambda functions. Such functions are also used in other programming languages, such as C# or Java.
They can be defined very simply with the parameter lambda
, the name of the variable and the expression that the function is to calculate:
This example also clearly shows why Python Lambdas are anonymous functions: The function itself cannot be given a name, it can only be stored in a variable (function
).
So if we want to recreate the sum
function from our initial example using Python lambdas, it looks like this:
As you can see, more than one argument can be passed to Python Lambdas. However, we cannot recreate the sum_difference
function with Python Lambdas, as the anonymous functions can only ever output one result. Instead, two different functions must be defined and also called twice:
There are various cases in which it can be useful to use Python lambdas:
- When simple functions are defined that only have one output and a small number of inputs. In large projects, it can make sense not to define such a function explicitly in order to save space and avoid unnecessary confusion. Furthermore, you save yourself problems with inheritance etc. in large classes.
- The same argument also applies if functions are only used once. Then you can do without the explicit definition, as nobody needs to access the function anyway.
- In addition, anonymous functions can ensure that the content of the function is quicker and easier to understand as it is defined in a single line. The explicit definition of functions can lead to a certain degree of comprehensibility being lost.
- Furthermore, there are functions in Python, such as
filter
ormap
, which take functions as input. In these cases, it therefore makes sense to use Python Lambda.
What are decorators in Python?
The so-called Python Decorators offer the possibility to change the functionality of a function. At first glance, this may seem pointless, as you can simply change the original function. In practice, however, the use of Python decorators can make perfect sense and help to make the code simpler and easier to understand.
When logging programs, decorators are often used to record which function was called and when. To avoid having to explicitly include these commands in every function, decorators are used to define the logging once centrally and then use it multiple times.
Let’s take a look at a simple example and use a simple function that simply outputs “Hello!”:
To do this, we can now define a function that documents the call to say_hello()
so that we can then determine whether the call worked and the function was executed as intended. To do this, we need to define a function in the function.
In our case, the outer function is log_decorator
, which uses a function func
as input. This outer function is used later for the decorator. If we did not define a second, inner function at this point, the function would only be called when the decorator is initially defined and not every time say_hello()
is called.
The inner function wrapper()
now describes the actual functionality, i.e. that there is first an output, then the function is called and then an output is made again:
Now the say_hello()
function must be redefined with the log_decorator
in front of it. A Python decorator can be recognized by the initial @ character.
The advantage of using the Python Decorator is that the wrapper function can be used again when the program is expanded. So if we now add another function, such as say_bye()
, we can also log it with the same decorator and do not have to define it additionally.
This is what you should take with you
- Functions are an important pillar in Python programming and allow certain logic and code components to be called multiple times.
- To define a function, you need the preceding keyword def, a name for the function and a series of parameters, which are defined in round brackets.
- The parameters can either be positional arguments, where the order of the values is decisive, or keyword arguments, where the value is assigned to the correct parameter via keywords.
- Recursion is a concept in which a function calls itself when running through the algorithm. This can be required, for example, when calculating the factorial.
- Lambda functions, or so-called anonymous functions, can be defined within a line and do not require a function name.
- The Python Decorator makes it possible to extend the functionality of a function without changing the original code.
What are Conditional Statements in Python?
Learn how to use conditional statements in Python. Understand if-else, nested if, and elif statements for efficient programming.
What is XOR?
Explore XOR: The Exclusive OR operator's role in logic, encryption, math, AI, and technology.
How can you do Python Exception Handling?
Unlocking the Art of Python Exception Handling: Best Practices, Tips, and Key Differences Between Python 2 and Python 3.
What are Python Modules?
Explore Python modules: understand their role, enhance functionality, and streamline coding in diverse applications.
What are Python Comparison Operators?
Master Python comparison operators for precise logic and decision-making in programming.
What are Python Inputs and Outputs?
Master Python Inputs and Outputs: Explore inputs, outputs, and file handling in Python programming efficiently.
Other Articles on the Topic of Functions in Python
The University of Stanford has an interesting article about functions in Python.
Niklas Lang
I have been working as a machine learning engineer and software developer since 2020 and am passionate about the world of data, algorithms and software development. In addition to my work in the field, I teach at several German universities, including the IU International University of Applied Sciences and the Baden-Württemberg Cooperative State University, in the fields of data science, mathematics and business analytics.
My goal is to present complex topics such as statistics and machine learning in a way that makes them not only understandable, but also exciting and tangible. I combine practical experience from industry with sound theoretical foundations to prepare my students in the best possible way for the challenges of the data world.