🤖Functions
FUNCTIONS
Last updated
FUNCTIONS
Last updated
In Python, a function is a group of related statements that performs a specific task.
A process for executing a task
It can accept input and return an output
Useful for executing similar procedures over and over
Stay DRY - Don't Repeat Yourself!
Clean up and prevent code duplication
Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organized and manageable.
Furthermore, it avoids repetition and makes the code reusable.
Above shown is a function definition that consists of the following components.
Keyword def that marks the start of the function header.
A function name to uniquely identify the function.
Parameters (arguments) through which we pass values to a function. They are optional
A colon (:) to mark the end of the function header.
Optional documentation string (docstring) to describe what the function does
One or more valid python statements that make up the function body. Statements must have the same indentation level (usually 4 spaces).
An optional return statement to return a value from the function.
Once we have defined a function, we can call it from another function, program or even the Python prompt. To call a function we simply type the function name with appropriate parameters.
The first string after the function header is called the docstring and is short for documentation string. It is briefly used to explain what a function does.
Although optional, documentation is a good programming practice. Unless you can remember what you had for dinner last week, always document your code.
In the above example, we have a docstring immediately below the function header. We generally use triple quotes so that docstring can extend up to multiple lines. This string is available to us as the _ _doc _ _ attribute of the function.
To learn more about docstrings in Python, visit Python Docstrings .
The return statement is used to exit a function and go back to the place from where it was called.
This statement can contain an expression that gets evaluated and the value is returned. If there is no expression in the statement or the return statement itself is not present inside a function, then the function will return the None object.
Here, None is the returned value since greet() directly prints the name and no return statement is used.
Functions that readily come with Python are called built-in functions. If we use functions written by others in the form of library, it can be termed as library functions.
All the other functions that we write on our own fall under user-defined functions. So, our user-defined function could be a library function to someone else.
User-defined functions help to decompose a large program into small segments which makes program easy to understand, maintain and debug.
If repeated code occurs in a program. Function can be used to include those codes and execute when needed by calling that function.
Programmars working on large project can divide the workload by making different functions.
Scope of a variable is the portion of a program where the variable is recognized. Parameters and variables defined inside a function are not visible from outside the function. Hence, they have a local scope.
The lifetime of a variable is the period throughout which the variable exits in the memory. The lifetime of variables inside a function is as long as the function executes.
They are destroyed once we return from the function. Hence, a function does not remember the value of a variable from its previous calls.
Here, we can see that the value of x is 20 initially. Even though the function my_func() changed the value of x to 10, it did not affect the value outside the function.
This is because the variable x inside the function is different (local to the function) from the one outside. Although they have the same names, they are two different variables with different scopes.
On the other hand, variables outside of the function are visible from inside. They have a global scope.
We can read these values from inside the function but cannot change (write) them. In order to modify the value of variables outside the function, they must be declared as global variables using the keyword global .
Here, the function greet() has two parameters.
Since we have called this function with two arguments, it runs smoothly and we do not get any error.
If we call it with a different number of arguments, the interpreter will show an error message. Below is a call to this function with one and no arguments along with their respective error messages.
Up until now, functions had a fixed number of arguments. In Python, there are other ways to define a function that can take variable number of arguments.
We can provide a default value to an argument by using the assignment operator (=). Here is an example.
In this function, the parameter name does not have a default value and is required (mandatory) during a call.
On the other hand, the parameter msg has a default value of "Good morning!" . So, it is optional during a call. If a value is provided, it will overwrite the default value.
Any number of arguments in a function can have a default value. But once we have a default argument, all the arguments to its right must also have default values.
This means to say, non-default arguments cannot follow default arguments. For example, if we had defined the function header above as:
We would get an error as:
When we call a function with some values, these values get assigned to the arguments according to their position.
For example, in the above function greet() , when we called it as greet("Bruce", "How do you do?") , the value "Bruce" gets assigned to the argument name and similarly "How do you do?" to msg .
Python allows functions to be called using keyword arguments. When we call functions in this way, the order (position) of the arguments can be changed. Following calls to the above function are all valid and produce the same result.
As we can see, we can mix positional arguments with keyword arguments during a function call. But we must keep in mind that keyword arguments must follow positional arguments.
Having a positional argument after keyword arguments will result in errors. For example, the function call as follows:
Will result in an error:
Sometimes, we do not know in advance the number of arguments that will be passed into a function. Python allows us to handle this kind of situation through function calls with an arbitrary number of arguments.
In the function definition, we use an asterisk (*) before the parameter name to denote this kind of argument. Here is an example.
Here, we have called the function with multiple arguments. These arguments get wrapped up into a tuple before being passed into the function. Inside the function, we use a for loop to retrieve all the arguments back.
Arbitrary Arguments are often shortened to *args in Python documentations.
Python passes variable length non keyword argument to function using args but we cannot use this to pass keyword argument. For this problem Python has got a solution called *kwargs , it allows us to pass the variable length of keyword arguments to the function.
In the function, we use the double asterisk before the parameter name to denote this type of argument. The arguments are passed as a dictionary and these arguments make a dictionary inside function with name same as the parameter excluding double asterisk .
In the above program, we have a function intro() with **data as a parameter. We passed two dictionaries with variable argument length to the intro() function. We have for loop inside intro() function which works on the data of passed dictionary and prints the value of the dictionary.
args and kwargs are special keyword which allows function to take variable length argument.
*args passes variable number of non-keyworded arguments list and on which operation of the list can be performed.
**kwargs passes variable number of keyword arguments dictionary to function on which operation of a dictionary can be performed.
args and *kwargs make the function flexible.
Recursion is the process of defining something in terms of itself.
A physical world example would be to place two parallel mirrors facing each other. Any object in between them would be reflected recursively.
In Python, we know that a function can call other functions. It is even possible for the function to call itself. These types of construct are termed as recursive functions.
The following image shows the working of a recursive function called recurse .
Following is an example of a recursive function to find the factorial of an integer.
Factorial of a number is the product of all the integers from 1 to that number. For example, the factorial of 6 (denoted as 6!) is 12345*6 = 720.
In the above example, factorial() is a recursive function as it calls itself.
When we call this function with a positive integer, it will recursively call itself by decreasing the number.
Each function multiplies the number with the factorial of the number below it until it is equal to one. This recursive call can be explained in the following steps.
Let's look at an image that shows a step-by-step process of what is going on:
Our recursion ends when the number reduces to 1. This is called the base condition.
Every recursive function must have a base condition that stops the recursion or else the function calls itself infinitely.
The Python interpreter limits the depths of recursion to help avoid infinite recursions, resulting in stack overflows.
By default, the maximum depth of recursion is 1000. If the limit is crossed, it results in RecursionError . Let's look at one such condition.
Recursive functions make the code look clean and elegant.
A complex task can be broken down into simpler sub-problems using recursion.
Sequence generation is easier with recursion than using some nested iteration.
Sometimes the logic behind recursion is hard to follow through
Recursive calls are expensive (inefficient) as they take up a lot of memory and time.
Recursive functions are hard to debug.
Click for further reading on python recursive function.
Python Anonymous/Lambda Function
In Python, an anonymous function is a function that is defined without a name.
While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword.
Hence, anonymous functions are also called lambda functions.
Lambda functions can have any number of arguments but only one expression. The expression is evaluated and returned. Lambda functions can be used wherever function objects are required.
In the above program, lambda x: x 2 is the lambda function. Here x is the argument and x 2 is the expression that gets evaluated and returned.
This function has no name. It returns a function object which is assigned to the identifier double . We can now call it as a normal function. The statement
is nearly the same as:
We use lambda functions when we require a nameless function for a short period of time.
In Python, we generally use it as an argument to a higher-order function (a function that takes in other functions as arguments). Lambda functions are used along with built-in functions like filter() , map() etc.
The filter() function in Python takes in a function and a list as arguments.
The function is called with all the items in the list and a new list is returned which contains items for which the function evaluates to True .
Here is an example use of filter() function to filter out only even numbers from a list.
The map() function in Python takes in a function and a list.
The function is called with all the items in the list and a new list is returned which contains items returned by that function for each item.
Here is an example use of map() function to double all the items in a list.
In Python, a variable declared outside of the function or in global scope is known as a global variable. This means that a global variable can be accessed inside or outside of the function.
Let's see an example of how a global variable is created in Python.
In the above code, we created x as a global variable and defined a foo() to print the global variable x . Finally, we call the foo() which will print the value of x .
What if you want to change the value of x inside a function?
The output shows an error because Python treats x as a local variable and x is also not defined inside foo() .
To make this work, we use the global keyword.
A variable declared inside the function's body or in the local scope is known as a local variable.
The output shows an error because we are trying to access a local variable y in a global scope whereas the local variable only works inside foo() or local scope.
Let's see an example on how a local variable is created in Python.
Normally, we declare a variable inside the function to create a local variable.
Here, we will show how to use global variables and local variables in the same code.
In the above code, we declare x as a global and y as a local variable in the foo() . Then, we use multiplication operator to modify the global variable x and we print both x and y .
After calling the foo() , the value of x becomes global global because we used the x 2 to print two times global . After that, we print the value of local variable y i.e local .
In the above code, we used the same name x for both global variable and local variable. We get a different result when we print the same variable because the variable is declared in both scopes, i.e. the local scope inside foo() and global scope outside foo() .
When we print the variable inside foo() it outputs local x: 10 . This is called the local scope of the variable.
Similarly, when we print the variable outside the foo() , it outputs global x: 5 . This is called the global scope of the variable.
Nonlocal variables are used in nested functions whose local scope is not defined. This means that the variable can be neither in the local nor the global scope.
Let's see an example of how a nonlocal variable is used in Python.
We use nonlocal keywords to create nonlocal variables.
In the above code, there is a nested inner() function. We use nonlocal keywords to create a nonlocal variable. The inner() function is defined in the scope of another function outer() .
Note : If we change the value of a nonlocal variable, the changes appear in the local variable.
Return the smallest item in an iterable or the smallest of two or more arguments.
Return the largest item in an iterable or the largest of two or more arguments.
Return the absolute value of a number. The argument may be an integer or a floating point number.
Takes an iterable and an optional start
Returns the sum of start and the items of an iterable from left to right and returns the total.
start defaults to 0
Make an iterator that aggregates elements from each of the iterables.
Returns an iterator of tuples, where the i -th tuple contains the i -th element from each of the argument sequences or iterables.
The iterator stops when the shortest input iterable is exhausted.
You can practice by copying the following document into your own environment.