Functions in Python

Functions in Python

In this article, we discuss about why functions are useful, and how they work syntactically. Also learn how to write our own functions. So, that we are able to design good programs which provide us reusability and modularity. We will learn how to create iteration easily using Python generators, how it is different from iterators and normal functions, and why we should use it. 

Functions in Python Learning Outcomes:

  • FUNCTION PARAMETERS VS. ARGUMENTS
  • TYPES OF FUNCTION
    • Function not returning available and no parameter passing
    • Function not returning a value but parameter passing
    • Function returning a value but no parameter passing
    • Function returning a value and parameter passing
  • FUNCTION WITH DEFAULT ARGUMENTS
  • FUNCTION WITH KEYWORD ARGUMENTS
  • FUNCTION WITH VARIABLE ARGUMENTS
  • SCOPE OF VARIABLES
  • ITERATORS IN PYTHON
  • GENERATORS IN PYTHON
    • Creating a Generator
    • Advantages of using Generators
    • Difference between a Generator Function and a Normal Function
    • Generator Expressions
  • RECURSION IN PYTHON
    • Recursive Fibonacci in Python
    • Tower of Hanoi in Python
    • Advantages of Recursive functions
    • Disadvantages of Recursive functions
  • HIGHER ORDER FUNCTIONS IN PYTHON
    • Functions as a first class objects
    • Lambda Functions

We can track a large or complex program easily when it is divided into smaller parts. Python allows us to divide a large program into basic building blocks known as function. Basically, their function is a piece of code written to perform some specified task. It can be called any number of times in a program and from any place in a program. By using functions, we can avoid rewriting same logic/code again and again in a program. Hence, we can say that functions provide reusability and modularity to the python program. Python gives us many built-in-functions like print(), range(), input() etc., and we can also define our own functions as per our need needs. These functions are called user-defined functions

The function block is started with the colon (:) and all the statements remain at the same indentation. A function can take any number of parameters that must be seen in the definition and function calling. Parameters are optional i.e. we may define parameters or may skip as per our requirement. 

Functions in Python

Calling a function:

In Python language, a function must be defined before the function calling otherwise an interpreter gives an error. Defining a function only gives it a name, specifies the parameter data are to be included in the function and structures the blocks of code. Once the function is defined, we can call it from another function or from the python prompt to execute statement(s) in the function body. The syntax for calling a function is as shown below:

# Syntax of calling a function
function_name(parameter(s)) #parameters will be passed only
#if defined in function definition

Example:

In this example, we defined a function called my_function using the syntax as explained above. It simply prints a message “Hello_Learner”. This function takes no parameter and hence there are no variables declared in the parentheses. Parameters to functions are just input to the function so that we can pass different values to it and get back corresponding results. 

# Program for demonstration of function
def my_function(): # function Header
print (“Hello_Learner”) #function Body
#End of function
print (“Learn with Fun”) # a statement outside the function body
my_function() # Function call

Output: 

Learn with Fun
Hello_Learner

1.1 FUNCTION PARAMETERS VS. ARGUMENTS:

Parameters are used to pass the values (information) to a Function so that the function can do something utilizing those values. Parameters are specified within the pair of parentheses in the function definition, separated by commas. When we call the function, we supply the values in the same way. This parameters are just like variables except that the values of this variables are defined when we call the function and are not assigned values within the function itself. 

Note: The names given in the function definition are called parameters whereas the values we supply in the function call are called arguments

Functions in Python

Return statement:

A return statement is used to end the execution of the function and returns the value of expression to the caller. It cannot be used outside the function. The statements are not executed after the return statement in a function. If return statement is without any expression, then a special value “None” is returned. The syntax of return statement is as given below:

#Syntax of using a return statement
def function_name (Parameter (s)): # parameters are optional
statement (s)



Return (expression)

Example:

# Program for demonstration of return statement
def add(a,b): # It takes two arguments
return(a+b) # Returning sum of a and b
res = add(3,4) # Calling a function
print (“sum of two numbers:”, res)

Output:

sum of two numbers: 7

1.2 TYPES OF FUNCTION

Functions can be categorized into four categories based on returning of value and parameters passing as given below:

  • Function not returning a value and no parameter passing 
  • Function not returning a value but parameter passing
  • Function returning a value but no parameter passing 
  • Function returning a value and parameter passing 

1.2.1 Function not returning available and no parameter passing:

This type of functions doesn’t return any value and also takes no parameters as shown below:

Example: 

# Program for demonstration of function
# which don’t return any value and takes no parameters
def my_add function():
n1 = int (input(“Enter the first number:”))
n2 = int (input(“Enter the second number:”))
ADD = n1 + n2
print (” Addition:”, ADD)
# End of function
my_add function() # Function call

Output:

Enter the first number: 23
Enter the second number: 12
Addition: 35

1.2.2 Function not returning a value but parameter passing:

This type of functions does not return any value but parameters are passed through this function as shown in example. 

Example:

Here, n1 and n2 are two parameters (inputs) to a function.

”’ Program for demonstration of function
which does not return any value but takes parameters ”’
def my_add function(n1, n2): # Function with two parameters
ADD = n1 + n2
print (“Addition:”, ADD)
# End of function
num1 = int(input(“Enter the first number:”))
num2 = int(input(“Enter the second number:”))
# Function call with 2 arguments
my_addition(num1, num2)

Output:

Enter the first number: 11
Enter the second number: 12
Addition: 23

1.2.3 Function returning a value but no parameter passing

This type of functions return a value but takes no parameters as shown below. 

Example:

# Program for demonstration of function
# returning a value but takes no parameters
def my_add function(): # Function Header without parameters
n1 = int(input(“Enter the first number:”))
n2 = int(input(“Enter the second number:”))
ADD = n1 + n2
return ADD # Return the value of ADD variable
#End of function

sum = my_add function() # Function assigns the returned value to variables
print (“Addition:”, sum) # Print the value at memory location sum

Output:

Enter the first number: 12
Enter the second number: 11
Addition: 23

1.2.4 Function returning a value and parameter passing

This type of functions returns a value and also takes parameters as shown in example below: 

Example:

# Program for demonstration of function
# returning a value and parameter passing
def my_add function(n1, n2): # Function Header with parameters n1 and n2
ADD = n1 + n2
return ADD # Return the value of ADD variable
# End of function

n1 = int (input(“Enter the first number:”))
n2 = int (input(“Enter the second number:”))
sum = my_add function(n1, n2) # Function assigns the returned value to variables
print (“Addition:”, sum) # Print the value at memory location sum

Output:

Enter the first number: 12
Enter the second number: 11
Addition: 23

1.3 FUNCTION WITH DEFAULT ARGUMENTS

In some functions, we may want to make some of its parameters use default values if the user does not want to provide values for such parameters. We can do this with the help of default arguments. A default argument is an argument that takes a default value if a value is not provided in the function call for that argument. We can specify default argument values for parameters by following the parameter name in the function definition with the assignment operator (=) followed by the default value. Note that the default argument value should be a constant. 

Example:

The function named my_add function is used to print addition of two numbers. If you don’t supply a value, then by default the sum is 8 because the default value of n1 and n2 is 3 and 5 respectively. Next time, we called a function with one argument and it prints the sum by taking n1=12 and n2 = 5 (Default value). In next function call, we supply two arguments. Here it prints the sum by taking n1= 22 and n2 = 12.

# Program for demonstration of function with default argument
def my_add function (n1 = 3, n2 = 5): #Default values of arguments n1 and
ADD = n1 + n2
return ADD # Return the value of ADD variable
# End of function
#Function call with no parameters, system assigns default value to n1 and n2
print (“Addition:”, my_add function())
#Function call with only 1 argument, it assigns n1=12 and n2=5
print (“Addition:”, my_add function(12))
#Function call with 2 arguments, it assigns n1=22 and n2=12
print (“Addition:”, my_add function(22,12))

Output:

Addition: 8
Addition: 17
Addition: 34

Note: Only those parameters which are at the end of parameter list can be given default arguments values i.e. we cannot have a parameter with a default argument value before a parameter without a default argument value in the order of parameters declared in the function parameter list. This is because the values are assigned to the parameters by position.

For example, def my_add function(n1,n2=5) is valid, but def my_addfunction(n1=5,n2) is not valid.

1.4 FUNCTION WITH KEYWORD ARGUMENTS

If we have some functions with many parameters and we do not want to specify all of them, then we can assign values for such parameters by naming them -this is called keyword arguments. Here, we use the name (keyword) instead of the position (which we are considering in case of default arguments) to specify the arguments to the function. This approach provides two advantages:

  • Using the function becomes easier now since we do not need to worry about the order of the arguments. 
  • We can give values to only those parameters Which we want, provided that the other parameters have default argument values. 

Example: 

The function named func has one parameter without default argument values, followed by two parameters with default argument values. First time when we call a func (6, 7), the parameter a gets the value 3, the parameter b gets the value 5 and c gets the default value of 10. Second time, we called this function as, func(12, c = 2), the variable a gets the value of 12 due to the position of the argument. Then, the parameter c gets the value of 2 due to naming i.e. keyword arguments. The variable b gets the default value of 8. In the third usage func(c=22, a=19), we use keyword arguments completely to specify the values. Notice, that we are specifying values of for parameters c before a even though a is defined before c is the function definition.

# Program for demonstration of function with keyword(s) argument
def func (a, b=8, c=45):
print (‘a is’, a, ‘and b is’, b ‘and c is ‘, c)
func (6,7)
func (12, c=2)
func (c=22, a=19)

Output:

a is 6 and b is 7 and c is 45
a is 12 and b is 8 and c is 2
a is 19 and b is 8 and c is 22

1.5 FUNCTION WITH VARIABLE ARGUMENTS

If we need to define a function with arguments which are not fixed. We can do this by using variable length arguments. These are not named in the function definition, unlike required and default arguments. 

The special syntax *args in function definition is used to pass a variable number of arguments to a function. It is used to pass a non-keyworded, variable length argument list. For example: we want to define a multiply function that takes any number of arguments and able to multiply them all together. It can be done using *args. Using a *, the variable that we associat with the * becomes an iterable which means we can do things like iterate over it, run some higher order functions such as map and filter etc. 

Example:

# Program for demonstration of function with variable arguments
def mul (*args):
result = 1
for num in args:
result *= num
print(result)
# End of function definition
mul (10) # Calling a function with 1 argument
mul (10, 20) # Calling a function with 2 argument
mul (10, 20, 30) # Calling a function with 3 argument

Output:

10
200
6000

1.6 SCOPE OF VARIABLES:

All variables have the scope of the block they are declared in, starting from the point of definition of the name. Variables that are defined inside a block or called local variables, and those defined outside the block are called global variables. Local variables can be used only within the block in which they are declared, whereas global variables can be used in the whole program. In case of a local and a global variable, preference is given to a local variable. 

Local variables, including function parameters have a life from the start of the execution of the function to the end of the execution i.e. the end of the function or the return statement. Global variables live from when module is imported until the end of the application- unless the variable is explicitly deleted. 

Example:

# Program for demonstration of scope of variables
a=2 # Global variable
print(a)
def display():
a=3 # a is also defined as Local variable inside a function
b=4
print(a) ”’ a is treated as local variable, as preference is given to a
local variable”’
print(b)
display() # Calling a function
print(a) # Here a is treated as a global variable

Output: 

2
3
4
2

Use of Global Statement: 

If we want to assign a value to a name defined outside the function, then we have to tell Python that the name is not local, but it is global. We do this using the global statement otherwise it is not all at all possible. We can use the values of such variables defined outside the function (assuming there is no variable with the same name within the function). However, this is not encouraged and should be avoided since it becomes unclear to the reader of the program as to whether the variable’s definition is. 

Example:

# Program for demonstration of Global Statement
def display():
global x # defining a global variable within a function
print (‘x is’, x)
x = 5
print (‘Changed global x to’, x)
x = 55
display()
print (‘Value of x is’, x)

Output: 

x is 55
Changed global x to 5
Value of x is 5
1.7 ITERATORS IN PYTHON : 

An iterator is an object that can be iterated upon. It will return one element at a time. An object is called iterable if we can get an iterator from it. Most of the built-in containers in Python like tuple, string, list etc. are iterable. There are many types of objects which can be used with a for loop. These are called iterable objects. For example:

  • We can use for statement for looping over a list. 
>>> for i in [1, 2, 3, 4]:
print(i)
1
2
3
4
  • We can use for statement with a string for looping over its characters. 
>>> for s in”string”:
print(s)
s
t
r
i
n
g
  • If you use it with a dictionary, it looks over its keys. 
>>> for d in (“x”: 11, “y”: 12):
print(d)
x
y

Any object that is that is to be used as an Iterator must implement the following two methods. 

  1. Iter() – The built-in function iter() takes an iterable object and returns an iterator. It is called on the initialization of an Iterator. 
  1. Next() – This method is used to iterate through all the items of an iterator. Together these two methods are called the Iterative Protocol. 

1.7.1 Custom Iterators: 

Now let us understand how we can implement custom Iterators in Python by using an example. In this example, we are building our own iterator as a class in which we are implementing_init_(), iter_() and_next_() methods. This iterator will works like built-in range() function. It starts printing from zero up to a user set number. 

Note: You will better understand this topic if you are aware about the concept of classes in Python. So, we would suggest you must read a little bit about classes before reading this topic. 

#Class to implement as iterator which works like a range() function
class Myrange:
def_init_(self, n):
self.i = 0
self.n = n

def_iter_(self):
return self

def_next_(self):
if self.i<self.n:
i = self.i
self.i = 1
return i
else:
raise StopIteration()

Here, the_iter_() method is what makes an object iterable. The return value of_iter_() is an iterator. It should have a_next_() method and raise StopIteration when there are no more elements.

1.7.2 Infinite iterators: 

It is not necessary that the item in an iterator object has to exhaust. There can be infinite iterators (which never ends). Following is an example to demonstrate infinite iterators. The built-in function iter() can be called with two arguments where the first argument must be called object (function) and second is the Sentinel. The iterator calls this function until the return value is equal to the Sentinel. 

The int() function always returns 0. So passing it as iter(int,1) will return an iterator that calls int() until the returned value equals 1. This never happens and we get an infinite iterator. 

The advantage of using iterators is that they save resources. Like shown above, we could get all the odd numbers without storing the entire number system in memory. We can have infinite items (theoretically) in infinite memory. Iterators also make our code look. Cool. 

1.8 GENERATORS IN PYTHON:

Generators simply the creation of iterators. There is too much trouble in building an iterator in Python, as we need to implement a class with_inter_() and_next_() method, keep track of internal states, and raise StopIteration when there are no values to be returned. This is both lengthy and unreasonable. All the work described above is automatically handled by generators in Python. Generators are basically functions that return traversable objects or items. These function do not produce all the items at once, rather they produce them one at a time only when required. 

1.8.1 Creating a Generator:

Creating a generator in Python is as easy as defining a normal function, but with a yield system instead of return statement. If a function contains at least one statement (it may contain other yield or return statements), then it becomes a generator function. Both yield and return will return some values from a function. The difference is that a return statement terminates a function entirely, whereas the yield statement pauses function, save all its states and later continues from there on successive calls. 

1.8.2 Advantages of using Generators: 

  • Without generators in Python, producing iterable is extremely difficult and lengthy. 
  • Generators easy to implement as the automatically implement_iter_(), and _next_() and StopIteration which otherwise, need to be explicitly specified. 
  • Memory is saved as the items are produced as when required, unlike normal Python functions.
  • Can be used to produce an infinite numbers of items. 
  • They can also be used to pipeline a number of operations. 

1.8.3 Difference between a Generator Function and a Normal Function

In Python, Generators are created just like how we create normal functions using the ‘def’ keyword, But, Generator functions make use of the yield keyword instead of return. This is done to notify the interpreter that this is an interior. Not just this, Generator functions are run when the next() function is called and noT by their name as in case of normal functions. 

1.8.4 Generator Expressions:

Generator expressions provide us another way to create generators in Python. Similar to the lambda functions which create anonymous functions, generator expressions create anonymous generator functions. The syntax for generator expression is similar to that of a list comprehension in Python. But the square brackets are replaced with round parentheses. The major difference between a list and comprehension and a generate expressions is that a list comprehension produces the entire list while the generator expression produce one item at a time. 

# Initialize the list
my_list = [1, 3, 6, 10]
gen_obj = (x**2 for x in my_list)

print (next(gen_obj))

print (next(gen_obj))

print (next(gen_obj))

print (next(gen_obj))

next (gen_obj)

When we run the above program, we get the following output:

1
9
36
100
Traceback (most recent: call last):
File “c:/Users/anushka/AppData/Local/Programs/Python/Python38-32/genobj.py”, line 14, in <module>
next (gen_obj)
StopIteration

We can use the generator expressions as argument to various functions that consume iterators. When used in such a way, the round parentheses can be dropped. 

>>> sum (x**2 for x in my_list)
146
>>> max (x**2 for x in my_list)
100
1.9 RECURSION IN PYTHON:

The process in which a function calls itself directly or indirectly is called recursion. and the corresponding function is called as recursive function. Using recursive algorithm certain problems can be solved quite easily like Tower of Hanoi, factorial etc. Recursion consists of two cases: Base Case and Recursive Case 

  • Base Case: Base Case is a condition where the function does not call itself anymore. It is also named as terminating condition. 
  • Recursive Case: It reduces the size of the given problem. 

Recursion without Base case will result Recursion Error. The Python interpreter limits the depths of recursion to avoid infinite recursions, resulting in stack overflows. By default, the maximum depth of recursion is 1000. If the limit is crossed, it results in Recursion Error. 

Now we will understand how a particular problem is solved using recursion. The idea is to be represent a problem in terms of one or more smaller problems and add one or more base conditions that stop the recursion. 

1.9.1 Recursive Fibonacci:

Fibonacci is a set of numbers that starts with a one or Zero, followed by a one end proceeds best on the rule that each number (called a Fibonacci number) is equal to the sum of the preceding two numbers. 

If the Fibonacci sequence is denoted by F(n), where n is the first term in the sequence, the following equations obtains for n = 0, where the first two terms are defined as 0 and 1 by convention: 

F(0) = 0, 1, 1, 2, 3, 5, 8, 13, 21……………

In some texts, it is a customary to use n =1. In that case, the first two terms are defined as 0 and 1 by default, and therefore:

F(1) = 1,1, 2, 3, 5, 8, 13, 21…………………. So, we can write this in Python as-

# Program to demonstrate Fibonacci
# This will return a fiboncci number on index n
def fib(n):
# Base case n =0 or n=1
if n ==0 or n ==1:
return n
# Recursive case
else:
return fib (n-1) + fib (n-2)

print (fib(8))

Output of above code is:

21

1.9.2 Tower of Hanoi:

Tower of Hanoi is a mathematical game or puzzle. It was invented by French mathematician Edward Lucas in 1883. It consists of three rods (pegs) and a number of disks of different size, which can slide onto any road. Three rods are named as Source, Destination and Auxiliary (one help to move the disks from source to destination). 

The puzzle starts with the disks in a neat stack in ascending order of size on one rod, smallest at the top, thus making a conical shape. The puzzle can be played with any number of risks. 

The objective of the puzzle is to move the entire stack to another rod, obeying the following rules:  

  • Only one disk must be moved at a time. 
  • Each move consists of taking the upper disk from one of the stacks and placing it on the top of another stack. A disk can only be moved if it is the uppermost disk on a stack. 
  • No larger disk can be placed on a top of a smaller disk. 

The minimum number of moves required to solve a Tower of Hanoi puzzle is 2n-1, where n is the number of disks. 

1.9.3 Advantages of Recursive functions:

  • Recursive functions make the code look clean and elegant. 
  • A complex task can be broken down into simple sub-problems using recursions. 
  • It is better in problem based on tree traversal/structures. 

1.9.4 Disadvantages of Recursive functions:

  • Recursive calls are inefficient as they take up a lot of memory and time. 
  • It can be slow, due to the overhead of maintaining stack. 
  • Recursive functions are harder to debug.

1.10 HIGHER ORDER FUNCTIONS 

A functions is called Higher Order Function if it contains other function(s) as a parameters or returns a function as an output. 

1.10.1 Functions as a first class objects:

Remember, all the data in a python program is represented by objects or relationship between objects. Things like the strings, lists, modules and functions are all objects. There is nothing particularly special about functions in Python. 

In different programming languages, First class objects are those objects which can be handled uniformly. They can be stored as data structure, as some parameters or some other functions, as control structures etc. A function in Python is called first class object if it satisfies the following properties. 

  • It is an instance of an object type.  
  • It can be stored as a variable. 
  • Pass it as an argument of some other function. 
  • It can be stored in list, set or some other data structures.

At first we will see how functions in Python can be used as an object. If function can be assigned to a variable in Python, this assignment does not call the function, instead a reference to that function is created. Consider the below example, for better understanding.

Example:

# Python program to illustrate functions can be treated as objects
def sen (text):
return text.upper()

print (sen(‘Python’))

# Assigning function to a variable
uppercase = sen

print (uppercase(‘Python’))

Output:

PYTHON
PYTHON

Passing Function as an argument to other function:

Functions in Python can be passed as an argument to other functions. Consider the below example, where we have created a function saying which takes a function as an argument. 

# Python program to illustrate functions can be passed as arguments to other run
def Uppsen (text):
return text.upper()

def Lowsen (text):
return text.lower()

def sen(func):
# storing the function in a variable
sentence = func(” Hi, I am passed as an argument.”)
print (sentence)

sen (Uppsen)
sen (Lowsen)

Output:

HI, I AM PASSED AS AN ARGUMENT.
hi, i am passed as an argument.

Returning function from another function:

As functions are objects, we can also return a function from another function. In the below example, the add function returns adder function. 

# Python program to illustrate functions can return another function

def add (x):
def adder(y):
return x + y

return adder

add_10 = add(25)

print (add_10(25))

Output:

50

1.10.2 Lambda Functions:

Lambdas, also known as anonymous functions are small, restricted functions which do not need a name (i.e., an identifier). Lambda functions were first introduced to the field of mathematics by Alonzo Church in the 1930s. Today, many modern programming languages like Java, Python, C, C++ support lambda functions to add functionally to the languages. In Python, Lambda expressions are utilized to construct anonymous functions. To do so, we will use the lambda keyword (just as we use def normal functions). Every anonymous function we defined in Python will have three essential parts. 

  • The Lambda keyword. 
  • The parameters are bound variables, and.
  • The function body. 

A Lambda function can have any number of parameters, but the function body can only contains one expression. Moreover, A Lambda is written in a single line of code and can also be invoked immediately. 

Syntax:  Lambda p1, p2: Expressions 

Here P1 and P2 are the parameters which are passed to Lambda function. We can add any number of parameters as per our requirements. Here brackets around the parameters are not required as we do with the regular functions. The last part (expression) is any valid Python expression that operates on the parameters we provide to the function. 

Example:

# Python program to illustrate Lambda Functions

adder = Lambda x,y: x + y
print (adder (1,2))

Output:

3

In above example, we have defined a variable adder that will hold the result returned by the Lambda function. Lambda keyword used to define this anonymous function. Then, we have passed two parameters x & y in the lambda function. In the body of the function, we added two parameters that we have passed. Notice that it is a single expression. We cannot write multiple statements in the body of a lambda function. After that we called the function and print the returned value. 

Frequently Asked Questions (FAQs)

Q.1 Write down the uses of default arguments in Python. 

Ans.1 In some functions, we may want to make some of its parameters use default values if the user does not want to provide values for such parameters. We can do this with the help of default arguments. A default argument is an argument that takes a default value if a value is not provided in the function call for that argument. We can specify default argument values for parameters by following the parameter name in the function definition with the assignment operator (=) followed by the default value. Note that the default argument value should be a constant.

Q.2 List the various features or functions in Python. 

Ans.2 Python allows us to divide a large program into basic building blocks known as function. Basically, their function is a piece of code written to perform some specified task. It can be called any number of times in a program and from any place in a program. By using functions, we can avoid rewriting same logic/code again and again in a program. Hence, we can say that functions provide reusability and modularity to the python program. Python gives us many built-in-functions like print(), range(), input() etc., and we can also define our own functions as per our need needs. These functions are called user-defined functions. 

The function block is started with the colon (:) and all the statements remain at the same indentation. A function can take any number of parameters that must be seen in the definition and function calling. Parameters are optional i.e. we may define parameters or may skip as per our requirement. 

TYPES OF FUNCTION:

Functions can be categorized into four categories based on returning of value and parameters passing as given below:

  • Function not returning a value and no parameter passing 
  • Function not returning a value but parameter passing
  • Function returning a value but no parameter passing 
  • Function returning a value and parameter passing 

Q.3 What are the difference between local variables and global variables.  

Ans.3 There are following difference between local and global variables.  

Local VariablesGlobal Variables
Variables that are defined inside a block are called local variables.Variables that are defined outside the block are called global variables.
Local variables can be used only within the block in which they are declared.Global variables can be used in the whole program.
Local variables including function parameters have a life from the start of the execution of the function to the end of execution i.e. the end of the function or the return statementGlobal variables live from where module is imported until the end of application- unless the variable is explicitly deleted.

Q.4 What do you mean by parameters used in functions? 

Ans. Parameters are used to pass the values (information) to a Function so that the function can do something utilizing those values. Parameters are specified within the pair of parentheses in the function definition, separated by commas. When we call the function, we supply the values in the same way. This parameters are just like variables except that the values of this variables are defined when we call the function and are not assigned values within the function itself.

Q.5 Explain in detail a function with variable length arguments. 

Ans.5 If we need to define a function with arguments which are not fixed. We can do this by using variable length arguments. These are not named in the function definition, unlike required and default arguments. 

The special syntax *args in function definition is used to pass a variable number of arguments to a function. It is used to pass a non-keyworded, variable length argument list. For example: we want to define a multiply function that takes any number of arguments and able to multiply them all together. It can be done using *args. Using a *, the variable that we associate with the * becomes an iterable which means we can do things like iterate over it, run some higher order functions such as map and filter etc.

Q.6 What do you mean by recursive function? Also write the advantages and disadvantages of recursion. 

Ans.6 The process in which a function calls itself directly or indirectly is called recursion. and the corresponding function is called as recursive function. Using recursive algorithm certain problems can be solved quite easily like Tower of Hanoi, factorial etc. Recursion consists of two cases: Base Case and Recursive Case.

Advantages of Recursive functions:

  • Recursive functions make the code look clean and elegant. 
  • A complex task can be broken down into simple sub-problems using recursions. 
  • It is better in problem based on tree traversal/structures. 

Disadvantages of Recursive functions:

  • Recursive calls are inefficient as they take up a lot of memory and time. 
  • It can be slow, due to the overhead of maintaining stack. 
  • Recursive functions are harder to debug.

Q.7 Explain Higher Order Functions in Python with an example. 

Ans. 7 A functions is called Higher Order Function if it contains other function(s) as a parameters or returns a function as an output. 

(a) Functions as a first class objects:

Remember, all the data in a python program is represented by objects or relationship between objects. Things like the strings, lists, modules and functions are all objects. There is nothing particularly special about functions in Python. 

In different programming languages, First class objects are those objects which can be handled uniformly. They can be stored as data structure, as some parameters or some other functions, as control structures etc. A function in Python is called first class object if it satisfies the following properties. 

  • It is an instance of an object type.  
  • It can be stored as a variable. 
  • Pass it as an argument of some other function. 
  • It can be stored in list, set or some other data structures.

(b) Lambda Functions:

Lambdas, also known as anonymous functions are small, restricted functions which do not need a name (i.e., an identifier). Lambda functions were first introduced to the field of mathematics by Alonzo Church in the 1930s. Today, many modern programming languages like Java, Python, C, C++ support lambda functions to add functionally to the languages. In Python, Lambda expressions are utilized to construct anonymous functions. To do so, we will use the lambda keyword (just as we use def normal functions). Every anonymous function we defined in Python will have three essential parts. 

  • The Lambda keyword. 
  • The parameters are bound variables, and.
  • The function body. 

Q. 8 What is the use of Iterators and Generators in Python? Explain. 

Ans.8 A. Iterators in Python:

An iterator is an object that can be iterated upon. It will return one element at a time. An object is called iterable if we can get an iterator from it. Most of the built-in containers in Python like tuple, string, list etc. are iterable. There are many types of objects which can be used with a for loop. These are called iterable objects.

For example:

  • We can use for statement for looping over a list. 
  • We can use for statement with a string for looping over its characters. 
  • If you use it with a dictionary, it looks over its keys. 

Any object that is that is to be used as an Iterator must implement the following two methods. 

  1. Iter() – The built-in function iter() takes an iterable object and returns an iterator. It is called on the initialization of an Iterator. 
  1. Next() – This method is used to iterate through all the items of an iterator. Together these two methods are called the Iterative Protocol. 

(a) Custom Iterators: 

Now let us understand how we can implement custom Iterators in Python by using an example. In this example, we are building our own iterator as a class in which we are implementing_init_(), iter_() and_next_() methods. This iterator will works like built-in range() function. It starts printing from zero up to a user set number.  

(b) Infinite iterators: 

It is not necessary that the item in an iterator object has to exhaust. There can be infinite iterators (which never ends). Following is an example to demonstrate infinite iterators. The built-in function iter() can be called with two arguments where the first argument must be called object (function) and second is the Sentinel. The iterator calls this function until the return value is equal to the Sentinel. 

The int() function always returns 0. So passing it as iter(int,1) will return an iterator that calls int() until the returned value equals 1. This never happens and we get an infinite iterator. 

The advantage of using iterators is that they save resources. Like shown above, we could get all the odd numbers without storing the entire number system in memory. We can have infinite items in infinite memory. Iterators also make our code look. Cool. 

B. Generators in Python:

Generators simply the creation of iterators. There is too much trouble in building an iterator in Python, as we need to implement a class with_inter_() and_next_() method, keep track of internal states, and raise StopIteration when there are no values to be returned. This is both lengthy and unreasonable. All the work described above is automatically handled by generators in Python. Generators are basically functions that return traversable objects or items. These function do not produce all the items at once, rather they produce them one at a time only when required. 

Creating a Generator:

Creating a generator in Python is as easy as defining a normal function, but with a yield system instead of return statement. If a function contains at least one statement (it may contain other yield or return statements), then it becomes a generator function. Both yield and return will return some values from a function. The difference is that a return statement terminates a function entirely, whereas the yield statement pauses function, save all its states and later continues from there on successive calls.

Advantages of using Generators: 

  • Without generators in Python, producing iterable is extremely difficult and lengthy. 
  • Generators easy to implement as the automatically implement_iter_(), and _next_() and StopIteration which otherwise, need to be explicitly specified. 
  • Memory is saved as the items are produced as when required, unlike normal Python functions.
  • Can be used to produce an infinite numbers of items. 
  • They can also be used to pipeline a number of operations. 

Functions in Python

Read More: https://digitalcomputereducation.com/fundamentals-of-python-programming/

Know More: https://www.youtube.com/watch?v=dyvxxJSGUsE

1 thought on “Functions in Python”

  1. Pingback: Computer Viruses -

Leave a Comment