Functions in Python
Learn about defining and using functions in Python.
Introduction
A function in Python is a block of code packaged together to perform a single related action.
The name ‘function’ comes from the fact that a block of code is trying to achieve a single functionality in the program. The main advantage of writing and using functions in Python is that it allows programmers to break their tasks into a group of reusable code.
There are two kinds of functions in Python:
- Built-in functions
- User-defined functions
Built-in functions
Built-in functions in Python are functions that come pre-written when you install Python and are readily available to use when coding.
You’ve already come across some built-in functions like print() and format() earlier on in this course. Here is a list of some commonly used built-in functions in Python:
Function Name | Functionality |
|---|---|
| Prints the specified message | |
| type | Returns the class type |
| len | Calculates the length of a string |
| abs | Returns the absolute value of a number |
| max | Returns the largest item in an iterable |
| min | Returns the smallest item in an iterable |
| sorted | Returns a sorted list |
Let's look at the output of these built-in functions:
print("Hello, World!") # Prints "Hello, World!"
print(type('5.5')) # Get the data type of the value '5.5'
print(len("apple")) # Get the length of the string "apple"
print(len([1, 2, 3, 4])) # Get the length of the list [1, 2, 3, 4]
print(abs(-7)) # Get the absolute value of -7
print(max(1, 3, 5, 2, 4)) # Get the largest value among the given numbers
print(min(1, 3, 5, 2, 4)) # Get the smallest value among the given numbers
print(sorted([4, 2, 7, 1, 5])) # Get a sorted list of the given numbersUser-defined Functions
User-defined functions in Python are functions that are defined by the user to perform a custom task/functionality. The general syntax for writing a user-defined function in Python is as follows:
def function_name(parameters):
"""
Docstring
"""
statement(s)
return [expression]
Once a function is written, it is very easy to use it. The syntax for using a function or ‘calling’ the function is as follows:
function_name(parameters)
As you can see, we can simply write the function name followed by a set of parenthesis to call a function. Any input to be supplied to the function is passed in the form of parameters (or arguments) which is written in between the set of parenthesis.
For example, let us look at the function below calculates the sum of two numbers and returns back the output:
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return totalRunning the above will not do anything because the function has yet to be called. Let's call it now with two parameters, 4 and 6:
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return total
print(sum_func(4, 6))The following things are happening when the sum_func is called:
- The value of
avariable is set as 4 and the value ofbvariable is set as 6. - The
totalvariable is calculated as 4 + 6 = 10. - The
totalvariable is returned back from the function.
We can also assign the value returned by a function to a variable.
output = sum_func(4, 6)
print(output)And, we can also specify the names of the arguments as well when calling the function.
output = sum_func(a=4, b=6)
print(output)*args and **kwargs in Python
*args and **kwargs allow you to pass multiple arguments or keyword arguments to a function. In the example below, we can use args and kwargs, if we need to pass in multiple arguments to a function and not just two parameters.
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return totalLet us start by looking at *args and achieve the same functionality as the above function.
def sum_func_with_args(*args):
"""
This function takes in multiple parameters and returns their sum.
"""
total = 0
for i in args:
total = total + i
return total
print(sum_func_with_args(4, 6, 8))Also, note that args is just a name and you can use any other word instead.
Next, let us look at **kwargs with which we can pass in multiple keyword arguments to a function.
def sum_func_with_kwargs(**kwargs):
"""
This function takes in multiple parameters and returns their sum.
"""
total = 0
for i in kwargs.values():
total = total + i
return total
print(sum_func_with_kwargs(a=4, b=6, c=8))Scope of a variable in a function
Whenever we create a variable inside of a function, the scope of the variable gets limited to that function.
This means that the variable can only be used within the function it is defined at. Such kinds of variables are known as local variables.
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return totalIn the above sum_func function, the variable a and b can only be used within the function itself and therefore, are local variables.
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return total
# If we try to print the value of 'a' outside the function, it will raise an error
print(a)On the other hand, if we declare a variable outside of a function, the scope of the variable is the entire program. This means that we can use it inside of user-defined functions as well. However, we cannot change the value of such variable from inside of a function.
# Initializing a variable outside of the function
increment = 5
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum with an increment.
"""
total = a + b + increment
return total
print(sum_func(4, 6))
print(increment) # Value is still 5 even after running the functionLet's try adding a local increment=10 variable inside the function and see the output.
# Initializing a variable outside of the function
increment = 5
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum with an increment.
"""
increment = 10 # This creates a new local variable 'increment' inside the function
total = a + b + increment
return total
print(sum_func(4, 6))
print(increment) # Value is still 5 even after running the functionTo change a variable declared outside of a function from within a function, we must use the global keyword to declare the variable inside the function. Such kinds of variables are known as global variables.
increment = 5
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum with an increment.
"""
global increment
increment = 10
total = a + b + increment
return total
print(sum_func(4, 6))
print(increment) # Value is now changed to 10 after running the functionIt means that when a global keyword is used inside a function, the variable refers to the global variable.
Special kinds of functions
In this section, we will be learning about two special kinds of functions in Python:
- Inner or Nested Function
- Recursive Function
But, before we dive deep into that, let us understand how a function can be called inside of another function.
def sum_func(a, b):
"""
This function takes in two parameters and returns their sum.
"""
total = a + b
return total
def square_sum(a, b):
"""
This function takes in two parameters and returns the square of their sums.
"""
total = sum_func(a, b)
squared_total = total ** 2
return squared_total
print(square_sum(4, 6))- Inner or Nested Functions in Python
A inner or nested function is a function that resides inside of another function.
def outer_func():
def inner_func():
print("Hello, World!")
return inner_func()
print(outer_func())This kind of function has direct access to variables and names defined in the enclosing function. Inner functions have many uses, most notably as decorator functions.
def outer_func():
a = 10
b = 20
def inner_func():
total = a + b
return total
return inner_func()
print(outer_func())- Recursive functions in Python
A recursive function is a user-defined function that calls itself. Recursiveness is very helpful in programming since it makes the code clean and makes it very easy to perform sequence generation.
For example, we can generate a sequence such as the following Fibonacci sequence using recursive function: 0, 1, 1, 2, 3, 5, 8, 13, 21, 24, ...
The first two terms of the Fibonacci sequence are 0 and 1. All other terms are obtained by adding the preceding two terms. This means to say the nth term is the sum of (n-1)th and (n-2)th term.
def recur_fibo(n):
"""
This function returns the nth term of the Fibonacci sequence.
"""
if n <= 1:
return n
else:
return(recur_fibo(n-1) + recur_fibo(n-2))
for i in range(10):
print(recur_fibo(i))The calculations happening in each loop are:
Loop | n | n-1 | n-2 | Printed Value |
|---|---|---|---|---|
| 1 | 0 | -1 | -2 | 0 |
| 2 | 1 | 0 | -1 | 1 |
| 3 | 2 | 1 | 0 | 1 |
| 4 | 3 | 2 | 1 | 2 |
| 5 | 4 | 3 | 2 | 3 |
| 6 | 5 | 4 | 3 | 5 |
| 7 | 6 | 5 | 4 | 8 |
| 8 | 7 | 6 | 5 | 13 |
| 9 | 8 | 7 | 6 | 21 |
| 10 | 9 | 8 | 7 | 34 |
Functional programming in Python
Functional programming in Python is a declarative programming paradigm where programs are created by applying sequential functions rather than statements. This form of programming decomposes a problem into a set of functions.
Here are some advantages of using functional programming:
- Easier debugging: Easier to find bugs as well as modify code.
- Modular code: Do not rely on external variables or states to function and can be reused easily.
- Parallel programming: Much easier to create parallel programs due to limited user input and states within the function.
Some of the functions that are widely used in Python are lambda(), map(), reduce() and filter() which we will discuss in this lesson.
- Lambda Function
A lambda function is a small anonymous function. Here is the syntax for writing a lambda function in Python:
lambda parameter:function_body
A lambda function contains the parameters to the left side of the colon (:) and the function body (code) at the right side of the colon. The result of running the body is returned by the function.
# Defining a lambda function to add two numbers
f = lambda a,b:a+b
print(f(4, 6))- Map Function
The map function takes in a function along with a collection of items. Upon running the function, the function is applied on each item of the collection and the resulting values are returned.
Here is the syntax for writing a map function in Python:
map(function, list_of_values)
# Defining a map function to calculate the length of each string in a list
x = list(map(len, ["apple", "car", "dog"]))
print(x)- Reduce Function
The reduce function takes in a function along with a collection of items. It returns a value that is created by combining the items.
Here is the syntax for writing a reduce function in Python:
reduce(function, list_of_values)
It can be imported from the functools module in Python. We haven't covered modules in this course yet, but you can think of them as libraries that contain pre-written code to perform specific tasks.
# Importing reduce function from functools module
from functools import reduce
# Defining a reduce function to calculate the product of all numbers in a list
x = reduce(lambda x,y: x*y, [1, 3, 1, 2, 4])
print(x)- Filter Function
The filter function takes in a function and a collection of items. It evaluates the function and returns a collection of every item for which the function returned True.
Here is the syntax for writing a filter function in Python:
filter(boolean_function, list_of_values)
# Defining a filter function to filter out values greater than 2 from a list
x = filter(lambda x:x>2, [0, 4, 2, 6, 1])
# Converting filter object to list to see the output
print(list(x))Advanced Concept: Decorators in Python
Decorators augment the behavior of other functions or methods. Any function that takes a function as a parameter and returns an augmented function can be used as a decorator.
def dummy_func(f):
return f
# Using the decorator
@dummy_func
def multiply_func(a, b):
return a * b
print(multiply_func(2, 4))This is similar to writing as:
final_func = dummy_func(multiply_func(2,4))
print(final_func)Typically, decorators are used when a function needs to perform something before another function is called.
Let us look at this example where the decorator function prints the arguments that the original function receives and then calls it.
def dummy_func(f):
def print_params(a, b):
print(a)
print(b)
return f(a, b)
return print_params
@dummy_func
def multiply_func(a, b):
return a * b
print(multiply_func(2, 4))