Python Functions

In this tutorial you will master all about Functions with examples in python; what is a function, what is the importance of function in a program, different types of functions, how to define and call a function, different types of arguments, etc. Besides these, you will cover the concepts of the scope of variables and recursion in python from beginner to expert levels.

What is a function?

A function necessarily is a free-standing block of code that is used to perform a particular task or related set of tasks. The function is primarily classified into two types. They are

  1. Built-in function
  2. User- Defined function

Throughout the prior tutorials, you have seen many examples of built-in functions namely len(),max() etc. A built-in function is a function that is built to python and end-users can access it to perform the specific task they want. On the other hand, a user-defined function is a function defined by the user to perform a particular task.

Going forward you will learn to create and execute your own function. Before that let’s discuss the benefits of using a function in a python program.

Significance of functions in programs

Functions play a vital role in all programming languages because of the following fair reasons.

  • Program readability increased
  • Allows code reusability in a compact manner
  • Modularity -Complex program is divided into smaller chunks
  • Avoids Redundancy
  • Minimizes the chance of errors

How define a function?

The basic syntax of the function is given below.


def < function_name >(< parameter(s) >):
  “ “ “ Doc_String ” ” ”
   < function _body >
   return(< expression >)
 

The components of the above function definition are tabulated below.

Components Description
def keyword def defines the beginning of a function header
< function_name > Should be a valid identifier.(refer rules of identifiers)
< parameter(s) > Used to pass values to the functions. Optional
: Indicates the end of the function header
“ “ “ Doc_String ” ” ” Used to provide the function documentation. Optional
< function _body > Valid python statements following same indentation level
return Returns the value of the function. Optional

An Example of a function illustrates how to print the area of a circle:


def area_calc():
 """this function gives the area of different shapes"""
pi =3.14
r = 10
print('Area is :',a)
 

In the above example, we have defined a function to print the area of a circle. This does not execute until a function call is made. A function definition stays inactive till the interpreter finds a function call.

How to call a function?

A function call is yet another important component of a python function. Once the creation of a function is completed, we need to execute the function by calling it from another function, program, or from the python prompt. To call a function, use the below syntax:

Python Function call syntax


< function_name >(< argument(s) >) 
 

Here In a function call, arguments refer to the values that are passed to the function. Arguments in a function call are synonymous with the parameters in the function definition. We can keep the arguments section empty however parentheses are a must in both function call and function definition.

Example of a function call:


# this is the function definition
def area_calc(r):
 """this function gives the area of circle"""
 pi = 3.14
 a = pi*r*r
 print('Area is :',a)

#This illustrates function call
area_calc(10)
area_calc(20)
 

Output:


Area is : 314.0
Area is : 1256.0

In this example, area_calc(10) and area_calc (20) are the functions calls with arguments 10 and 20.

How function works in python

So far in this tutorial, we have discussed all the components used in a python function in detail. Now let’s learn the overall working of the function and execution sequence.

Python Function working

A function in a program becomes active only when a function has called. The function call passes the control to the function where it performs a specific task by executing the body of the function. The final result will be returned to function call when it encounters a return statement or else it outputs the result in function and immediately terminates the function.

Note: Arguments are often represented as arg or args in python.

Python function arguments

Another important component of the function is the arguments. Arguments are defined after the function_ name inside parenthesis. Arguments should be separated using commas and the number of arguments is not limited to any number.

In the previous example area_calc(10) and area_calc(20) introduces the use of a single argument in a function call. These arguments are passed to the parameter ‘r’ in the function definition on each function call and accept the values 10 and 20 to finish the task.

Arguments are broadly classified into 4 types.

  1. Required Arguments

    Required Arguments otherwise known as positional arguments are the simplest way of passing arguments to a function in python. Since the arguments in function call correspond to the parameters in the function definition, the number and position(order) of arguments passing should be well considered.

    #this is function definition
    def person(name, age, place):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    # this is function call
    person('Chris',17,'USA')
     
    

    Output:

    
    Hi,Iam Chris 17 years lives in  USA
    

    In the above example function call person(‘Chris’,17,’USA’) has 3 arguments and function definition person(name,age,place) has 3 parameters.Here the parameters in the function definition act as a variable to hold the values from the function call. The parameters are defined locally to the function and when the function is called the arguments are passed to parameters in the same order respective to their position. Hence known as positional arguments.

    The below-given visualization gives clarity to the concept.

    Python Function - Required Arguments

    Note: The order of arguments passed must correspond to the order of parameters in a function.

    In case you pass the positional arguments out of order, what will happen? Obviously, the function executes as it is however the outcome may not be correct as you expected. For instance, person(‘USA’,17,’Chris’) produces the outcome as Hi, Iam USA 17 years old lives in Chris which is not the expected result.

    While considering the case of a number of arguments to be passed, like order , a number of arguments should bound to a number of parameters in the function. The following example explains the fact how this argument got the name required argument.

    Example: one extra argument

    
    def person(name, age, place):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    person('Chris','Jake',17,'USA',)
     
    

    Output:

    
    person('Chris','Jake',17,'USA',)
    TypeError: person() takes 3 positional arguments 
    but 4 were given
    
    

    Example: one argument missing

    
    def person(name, age, place):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    person('Chris',17)
     
    

    Output:

    
    person('Chris',17)
    TypeError: person() missing 1 required positional argument: 'place'
    

    Here the two examples imply that the number of arguments passed to the function must match with the parameters in the function definition. If we add or miss one argument then the result will be an error.

    In a nutshell,when a function is called the required argument or positional argument in python must specify the appropriate number of arguments to be passed, exactly in the same order of parameters in the function definition.

    Note: The number of arguments passed must match the number of parameters in a function.

  2. Keyword Arguments

    Keyword arguments in python are introduced to relax some of the restrictions of the required arguments. Keyword arguments take the form =,when we are calling a function. Here each keyword must counterpart a parameter in the function definition. Let’s see how we can modify the previous example with keyword arguments.

    Example: to illustrate the use of Keyword Arguments in Python:

    
    #this is function definition
    def person(name, age, place):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    # this is function call
    person(name='Chris',age=17,place ='USA')
    person(age=17,place ='USA',name='Chris')
     
    

    Output:

    
    Hi ,Iam Chris 17 years old lives in  USA
    Hi ,Iam Chris 17 years old lives in  USA
    

    In the above example, you can notice that the arguments in the highlighted function call are out of order. Still, it outputs the correct answer. This indicates that order is not a matter when keyword arguments are specified in a function call which means the caller function identifies the appropriate argument designated to the parameter by its name.

    Example: Keyword referencing to an undeclared parameter

    
    def person(name, age, place):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    person(name='Chris',age=17,country ='USA')
     
    

    Output:

    
    person(name='Chris',age=17,country ='USA')
    TypeError: person() got an unexpected keyword argument 'country'
    

    The example shows what happens when a keyword references an undeclared parameter in a function. It generates an exception. So it is essential to use the same name for both parameter and keyword.

    Keyword arguments allow ease only in the order of arguments to be passed but not in the number of arguments to be passed. An exception will arise when the number of arguments in the function call does not match the number of parameters, as in positional arguments.

  3. Default Arguments

    A default argument, as its name suggests, assumes a default value for a function parameter that misses the argument value during a function call. Default arguments are defined in function definition where parameters take the form =, where the is the default value for that parameter. The following example clarifies the concept of default argument:

    
    #this is function definition
    def person(name='Tom', age=20, place ='UK'):
     print(' Hi ,Iam',name ,age,'years old lives in ',place)
    
    # this is function call
    person('Chris',17,'USA')
    person('Chris')
     
    

    Output:

    
    Hi ,Iam Chris 17 years old lives in  USA
     Hi ,Iam Chris 20 years old lives in  UK
    

    In this example

    From this, we can infer that default arguments lift the restriction on the number of arguments by allowing omission of arguments during the function call.

    • During the function call person('Chris',17,'USA') , all argument values are passed to the function parameter and hence it produces the result “ Hi ,Iam Chris 17 years old lives in  USA”.

    • The second function call person('Chris'), passes only one argument value to the function, missing the other two argument values. Even then it generates the result “Hi ,Iam Chris 20 years old lives in  UK” by taking the default values set to the parameters in a function.

  4. Arbitrary Arguments / Variable-Length Arguments

    Python allows the use of variable length arguments(arbitrary arguments) in function definition to handle some situations where we are not pretty sure about the number of arguments a function needs. Based on the type of arguments it is classified into two types :

    • Nonkeyword arbitrary arguments

      Arbitrary arguments are typically defined by placing an (*) asterisk sign before the parameter, for instance, *args. *args are also known as non-keyword arbitrary arguments.

      Whenever a parameter is prefixed with an asterisk sign, it denotes the tuple packing of arguments. The arguments in the function call are packed into a tuple which a function refers to by its parameter name. The below image gives the visualization of the tuple packing of arguments. tags are the parameter in the function definition and arg1, arg2, arg3, …, argn  are the arguments passed during the function call

      Python Non keyword arbitrary arguments

      An example of a function definition with variable length arguments is displayed below:

      
      def fn(*names):
       print(names ,' belongs to',type(names) )
       for i in names:
        print(i)
      
      fn('Red','Green','Blue')
      print('\n')
      fn('Bike','Car','Bus','Train')
       
      

      Output:

      
      ('Red', 'Green', 'Blue')  belongs to 
      Red
      Green
      Blue
      
      ('Bike', 'Car', 'Bus', 'Train')  belongs to 
      Bike
      Car
      Bus
      Train
      

      In the above example

      • *names is the arbitrary argument and it accepts the arguments of arbitrary length during each function call.
      • fn('Red','Green','Blue') and fn('Bike','Car','Bus','Train')are the two function calls having 3 and 4 arguments respectively . These arguments are stored as tuples before passing to function and the for loop inside the function retrieves each argument and produces the result.
    • Keyword arbitrary Arguments (**kwargs)

      Now we have learned what *args is and how is it useful, lets check what is **kwargs in python function and how is it useful.

      **kwargs is used for passing keyword arguments to a function.**kwargs works the way *args, but it takes up keyword arguments despite the positional arguments. Function denotes the use of keyword arbitrary arguments by prefixing the parameter with a double asterisk(**). **asterick denotes the dictionary packing of arguments in the form Key: values.

      An example to show the working of **kwargs is given below:

      
      # **Kwargs example
      def fn(**names):
       print(names ,' belongs to',type(names) )
       for key, value in names.items():
        print("{} = {}".format(key,value))
      
      fn(Colour_1='Red',Colour_2= 'Green', Colour_3 ='Blue')
      fn(Vehicle_1= 'Bike',Vehicle_2 ='Car',Vehicle_3='Bus',Vehicle_4 ='Train')
      
       
      

      Output:

      
      {'Colour_1': 'Red', 'Colour_2': 'Green', 'Colour_3': 'Blue'}  belongs to 
      Colour_1 = Red
      Colour_2 = Green
      Colour_3 = Blue
      
      {'Vehicle_1': 'Bike', 'Vehicle_2': 'Car', 'Vehicle_3': 'Bus', 'Vehicle_4': 'Train'}  belongs to 
      Vehicle_1 = Bike
      Vehicle_2 = Car
      Vehicle_3 = Bus
      Vehicle_4 = Train
      

      Here in this example, we have called two functions of arbitrary length to the function named fn(**names) where **names is the keyword argument . ** names accepts the keywords in the form key value pairs which means as a dictionary. The ‘for loop’ inside the function retrieves each item and produces the result.

The Return Statement

The syntax of a return statements is


return (< [removed]s) >) 
 

The return statement in a python function is an optional statement that serves two fair purposes:

  1. The return statement rapidly exits the functions and shifts the control back to the caller.
  2. The return statement optionally passes some expressions or values to the caller .

The function passes a None object in two cases

  • when it finds a return statement with no arguments
  • when the return statement itself is not mentioned in the function.

The following example illustrates the use of return statement in a function:


def area_calc(x,y):
 return(x*y)


a = area_calc(10,15)
print('Area is :',a)

 

Output:


Area is : 150

What is an Anonymous Function

An anonymous function in python is a function with no name. Anonymous functions are defined using the Lambda keyword. Therefore, anonymous functions are also referred to as Lambda functions in python. 

Syntax of Anonymous function is:


lambda arg(s) : expression
 

An anonymous function can take as many arguments as it requires but must have only one expression. They cannot take multiple expressions and commands. Lambda functions are useful in places where a function object is required.

For instance, let's change the previous example in the form of the lambda function;


area_calc =lambda x ,y : x*y

print('Area is ',area_calc(10,20))

 

Output:


Area is  200

In this example,

  • lambda x ,y : x*y is the lambda function
  •  x and y are the arguments of lambda function 
  • x*y is the expression
     

The expression got evaluated and the value is returned as a function object which is assigned to the identifier area_calc. Now the anonymous function becomes a normal function.

Scope of variables in Functions

Scope of variables is one of the most important topics to be addressed while learning a programming language. Scope of a variable specifies the access of a variable in a function, in class, or in a program. Based on the scope and lifetime of a variable, python has divided variables into two types

  1. Global Variable - Global variables are variables declared outside the function and in the global scope. To be specific a global variable can be accessed inside the function and outside the function. The variable is active for the entire program.
  2. Local Variable - Local variables on the other hand are declared inside the function and in the local scope. More precisely, we can say local variable accessibility is restricted to the local function and it can’t be accessed outside the function.

The following example illustrates the scope of variable in function:


a = 0  # a is the global variable
def area_calc(x,y):  # x and y are local variables
 a=x*y
 print('Area is ',a)  # inside function

area_calc(10,20)
print('Area is ',a)  #outside function
print (x*y)        #outputs error as x and y are declared inside function
 

Output:


Area is  200
Area is 0

print (x*y)
NameError: name 'x' is not defined

Python Recursion

Recursion is the process of calling a function by itself. A function is said to be recursive if the function calls itself and such calls are known as recursive calls. More specifically a function will call the function repeatedly until it reaches the base case. The common structure of a recursive has two components :

  • Base case: the ultimate case in a recursive function that stops the recursion. 
  • Recursive case:  is the case that makes the recursive call

The following program illustrates the recursion process in python to find the factorial of a number. Before going to the program let us recall how to find the factorial of number 5.

Generalized way of finding factorial Example : 5!
n!= n x (n-1)! 5! = 5 x 4!
n!= n x (n-1) x (n-2)! 5! = 5 x 4 x 3!
n!= n x (n-1) x (n-2) x (n-3)! 5! = 5 x 4 x 3 x2!
  5! = 5 x 4 x 3 x2 x1!
n!= n x (n-1) x (n-2) x (n-3) ….3! 5! = 5 x 4 x 3 x2 x1 =>120
n!= n x (n-1) x (n-2) x (n-3) ….3 x 2!  
n!= n x (n-1) x (n-2) x (n-3) ….3 x 2 x1!  

Generalized way of finding factorial

 From the above table, we understand that a large problem is decomposed into smaller chunks of the same problem and repeats the process until we reach a base case. Here in this example 1! Is the base case with value 1.