Python Functions
Functions are a convenient way to divide your code into useful blocks, allowing us to order our code, make it more readable, reuse it and save some time. Also functions are a key way to define interfaces so programmers can share their code.

Types of Functions :

There are two types of Functions.

a) Built-in Functions : Functions that are predefined. We have used many predefined functions in Python.
b) User- Defined : Functions that are created according to the requirements.

Defining a Function : 

  • Function blocks begin with the keyword def followed by the function name and parentheses ( ( ) ). 
  • Keyword def is used to start the Function Definition. Def specifies the starting of Function block.
  • Any input parameters or arguments should be placed within these parentheses. You can also define parameters inside these parentheses.
  • The first statement of a function can be an optional statement - the documentation string of the function or docstring.
  • The code block within every function starts with a colon ( : ) and is indented.
  • The statement return [expression] exits a function, optionally passing back an expression to the caller. 
  • One or more valid python statements that make up the function body. Statements must have same indentation level (usually 4 spaces).
  • An optional return statement to return a value from the function.
Syntax :
>>> def square(x):
	return x * x
>>> square (6)

Calling a Function

Defining a function only gives it a name, specifies the parameters that are to be included in the function and structures the blocks of code.

Example :
>>> def func_1():
	print ("I am learning python tutorial.")

>>> func_1()
I am learning python tutorial.

return Statement :

return[expression] is used to send back the control to the caller with the expression.

In case no expression is given after return it will return None.

In other words return statement is used to exit the Function definition.

Example :
>>> def nsquare(x, y):
	return (x*x + 2*x*y + y*y)

>>> print("The square of the sum of 2 and 3 is : ", nsquare(2, 3))
The square of the sum of 2 and 3 is :  25

Python Function Arguments

Function arguments can have default values in Python. We can provide a default value to an argument by using the assignment operator (=).

A default value can be written in the format "argument1 = value", therefore we will have the option to declare or not declare a value for those arguments. See the following example.

Example :
>>> def nsquare(x, y = 2):
	return (x*x + 2*x*y + y*y)

>>> print("The square of the sum of 2 and 3 is : ", nsquare(2))
The square of the sum of 2 and 3 is :  16
>>> print("The square of the sum of 2 and 4 is : ", nsquare(2,4))
The square of the sum of 2 and 4 is :  36

Keyword Arguments

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 result.

Example :
>>> def ages(ramana, chanti = 27, suresh = 23):
	print('Ages is : Ramana is - ', ramana,', Chanti - ',chanti, ', Suresh - ',suresh)

>>> ages(28, 25)
Ages is : Ramana is -  28 , Chanti -  25 , Suresh -  23
>>> ages (27, suresh = 22)
Ages is : Ramana is -  27 , Chanti -  27 , Suresh -  22
>>> ages(suresh = 24, chanti = 26, ramana = 27)
Ages is : Ramana is -  27 , Chanti -  26 , Suresh -  24
Example :
>>> def printme( str ):
	"This prints a passed string into this function"
	print (str)

>>> printme( str = "My string")
My string

Arbitrary Arguments

The arbitrary argument list is an another way to pass arguments to a function. In the function body, these arguments will be wrapped in a tuple and it can be defined with *args construct. Before this variable, you can define a number of arguments or no argument.

Example :
>>> def greet(*names):
   """This function greets all
   the person in the names tuple."""
   for name in names:
>>> greet("Venkat","Ramana","Chanti","Suresh")
Hello Venkat
Hello Ramana
Hello Chanti
Hello Suresh

The Anonymous Functions

These functions are called anonymous because they are not declared in the standard manner by using the def keyword. You can use the lambda keyword to create small anonymous functions.

An anonymous function cannot be a direct call to print because lambda requires an expression

We use lambda functions when we require a nameless function for a short period of time.

Lambda forms can take any number of arguments but return just one value in the form of an expression. They cannot contain commands or multiple expressions.

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.

Lambda functions have their own local namespace and cannot access variables other than those in their parameter list and those in the global namespace.

Example :
>>> # lambda functions Program
>>> double = lambda x: x * 3
>>> print(double(9))

n 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

double = lambda x: x * 2

Python Recursive Function

Recursion is a way of programming or coding a problem, in which a function calls itself one or more times in its body. Usually, it is returning the return value of this function call. If a function definition fulfils the condition of recursion, we call this function a recursive function.

Following is an example of 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.

Example :
>>> def factorial(n):
	print("factorial has been called with n = " + str(n))
	if n == 1:
		return 1
		res = n * factorial(n-1)
		print("intermediate result for ", n, " * factorial(" ,n-1, "): ",res)
		return res

>>> print(factorial(5))
factorial has been called with n = 5
factorial has been called with n = 4
factorial has been called with n = 3
factorial has been called with n = 2
factorial has been called with n = 1
intermediate result for  2  * factorial( 1 ):  2
intermediate result for  3  * factorial( 2 ):  6
intermediate result for  4  * factorial( 3 ):  24
intermediate result for  5  * factorial( 4 ):  120