Functions in Python
Functions in Python
Types of Functions
1. In-built Functions: They’re built into Python and utilized without im-
porting any library. E.g. print(), input(), len()
1
2. Library Functions: They’re the functions that can be used by importing
them from libraries like, string, math, numpy, os etc. E.g. : log(),
random(), calendar().
3. String-Methods: These also do not need to be used after importing a
library but are limited to strings, thus are called string methods. E.g.
count(), strip(), index(), lower() etc.
4. User - Defined Functions: We can define and use these functions. E.g.
The factorial function.
• $ Every function is always followed by a parenthesis.
Call by Value
• Whenever we define a function and assign a parameter to it, the assigned
parameter is passed to the function as a value and not the variable itself.
E.g.:
def function(u):
prod = 2*u
return prod
u = 25
print(function(u))
Here, when we say u = 25 and pass u to the function, only the value of u is
passed to the function, thus we are calling the function by value.
A = []
A.append(r1)
A.append(r2)
A.append(r3)
s1 = [1, 2, 1]
2
s2 = [6, 2, 3]
s3 = [4, 2, 1]
B = []
B.append(s1)
B.append(s2)
B.append(s3)
dim = 3
# C[i][j] is the dot product of the ith row of A and the jth column of B
for i in range(dim):
for j in range(dim):
for k in range(dim):
C[i][j] = C[i][j] + A[i][k]*B[k][j]
print(C)
# Test Case
print(initialize_matrix(3))
• Secondly we make a Dot Product function.
def dot_product(row:list,column:list):
if len(row) != len(column):
raise ValueError("Mismatched dimensions for row and column.")
answer = 0
dim = len(row)
for i in range(dim):
3
answer += (row[i] * column[i])
return answer
# Test case
result = dot_product([25,1,17], [22,5,21])
print(result)
• Now we need to just place the dot products in a matrix. For this we define
a function that iterates through the i'th row and the j'th column.
def row_iterator(M:list,i:int) -> list:
dim = (len(M))
l_row = []
for k in range(dim):
l_row.append(M[i][k])
return l_row
# test
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(row_iterator(A, 0))
• Now we write a column iterator in same fashion.
def column_iterator(M:list, j:int) -> list:
dim = len(M)
l_column = []
for k in range(dim):
l_column.append(M[k][j])
return l_column
# testcase
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(column_iterator(A, 0))
• Now for the final part, we need to define the matrix multiplication as a
function.
# Getting all other functions too so that code runs.
def initialize_matrix(dim):
C = []
for i in range(dim):
C.append([])
for i in range (dim):
for j in range(dim):
C[i].append(0)
return C
#-------------------------------------------------------------------
def dot_product(row:list,column:list):
if len(row) != len(column):
raise ValueError("Mismatched dimensions for row and column.")
4
answer = 0
dim = len(row)
for i in range(dim):
answer += (row[i] * column[i])
return answer
#-------------------------------------------------------------------
def row_iterator(M:list,i:int) -> list:
dim = (len(M))
l_row = []
for k in range(dim):
l_row.append(M[i][k])
return l_row
#-------------------------------------------------------------------
def column_iterator(M:list, j:int) -> list:
dim = len(M)
l_column = []
for k in range(dim):
l_column.append(M[k][j])
return l_column
#-------------------------------------------------------------------
def matrix_multiplication(A:list, B:list) -> list:
dim = len(A)
C = initialize_matrix(dim)
for i in range(dim):
for j in range(dim):
C[i][j] = dot_product( row_iterator(A, i), column_iterator(B, j))
return C
#-------------------------------------------------------------------
# Test Case:
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
B = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix_multiplication(A, B))
Iterators
• iter(collection_name) will act as a basket does in real life. It becomes
an accumulation of elements and we can toggle through it. It converts
5
any iterable entity into an iterator E.g. :
fruits = [ 'Apple', 'Mango', 'Grapes', 'Banana' ]
basket = iter(fruits)
print(next(basket))
print(next(basket))
print(next(basket))
→As evident, basket acts like a basket does in real life due to the iter() key
word. Thus it is an iterator. Also notice that a list is iterable, thus converted
into an iterator. Had it been an integer, we couldn’t have converted it into an
iterator.
• When we iterate using a loop, internally it does the same thing as an
iterator, but we do not have the same control over it as an iterator.
Generators
• We may be interested in iterating through without creating a list or string.
In such cases we may use a Generator. In a generator we use yield
instead of return and we may toggle through different yields using the
next() function like we do in any iterator. E.g. :
def square(limit):
x = 0
while x < limit:
yield x
yield x*x
x += 1
a = square(5)
print(next(a), next(a))
print(next(a), next(a))
print(next(a), next(a))
print(next(a), next(a))
→ We’ve successfully written a generator above. We may have more than one
yield and toggle through them using next().
6
function. It reduces the length of our program. E.g. :
add = lambda x, y: x+y
subtract = lambda x, y: x-y
print(add(10, 20))
print(subtract(30, 20))
→ We see that the function runs without any errors. lambda functions are of
form : function_name = lamda arg_1, arg_2: function_definition
• The function is stored inside the variable name assigned to it. The function
call is just as usual.
Zip
• We may want to couple elements from two different lists. For that we may
use the zip(list_1, list_2) function.
• The arguments inside the zip() function are the two lists we are coupling.
• E.g. :
fruits = [ 'Apple', 'Mango', 'Grapes', 'Banana' ]
fruit_count = [2, 4, 25, 12]
print(list(zip( fruits, fruit_count)))
print(dict(zip(fruits, fruit_count)))
7
Map Function
• Let’s say we need to subtract a matrix B (list form) from another matrix
A (list form).
• map( function_name, list_1, list_2). Map takes the name of the
function and then the names of the lists to be mapped. E.g. :
a = [10, 20, 30, 40, 50]
b = [5, 10, 15, 20, 25]
Filter Function
• It is used to filter elements out as the name suggests. filter(condition,
list_name / input variable name) E.g.
import math
def square_root(n):
return math.sqrt(n)
def is_positive(n):
if n >= 0:
return n
output = map(square_root, filter(is_positive,a))
print(list(output))