Functions in Python
Function
• A function is a block of code which only runs when it is
  called.
• You can pass data, known as parameters, into a
  function.
• A function can return data as a result.
Example
def my_function():
 print("Hello from a function")
              Defining Functions
Function definition begins with      Function name and its
“def.”                               arguments.
                   def get_final_answer(filename):
                      “““Documentation
                      String””” line1
                      line2                                    Colon.
                      return     total_counter
 The indentation
 matters… First line
 with less                        The keyword ‘return’ indicates
 indentation is considered to     the value to be sent back to
 be outside of the function       the caller.
 definition.
No header file or declaration of types of function or
arguments
         Python and Types
 Dynamic typing: Python determines the
 data types of variable bindings in a
 program automatically
 Strong typing: But Python’s not casual
 about types, it enforces the types of
 objects
 For example, you can’t just append an
 integer to a string, but must first convert
 it to a string
 x = “the answer is ” # x bound to a
 string y = 23      # y bound to   an
         Calling a Function
 The syntax for a function call is:
    >>> def myfun(x, y):
            return x * y
    >>>      myfun(3, 4)
    12
 Parameters in
  Python are Call by
  Assignment
 • Old values for the variables that are
   parameter         names are hidden, and
   these variables are simply made to
   refer to the new values
 •
   Functions           without returns
 All functions in Python have a return
 value, even if no return line inside the
 code
 Functions without a return return the
 special value None
 •None is a special constant in the
  language
 •None is used like NULL, void, or nil in
  other      languages
 •None is also logically equivalent to
  False
 •The interpreter’s REPL doesn’t print
   Function overloading? No.
 There is no function overloading in
  Python
  • Unlike C++, a Python function is
    specified by   its name alone
  The number, order, names, or types of
  arguments cannot be used to distinguish
  between two functions with the same
  name
 • Two different functions can’t have the
   same       name, even if they have
   different arguments
 Default Values for Arguments
 You can provide default values
 for a function’s arguments
 These arguments are optional
 when the function is called
>>>        def myfun(b, c=3,
               d=“hello”):
          return         b   +
               c
>>> myfun(5,3,”hello”)
>>> myfun(5,3)
>>> myfun(5)
All of the above function calls
       Keyword Arguments
 Can call a function with some/all of its
 arguments out of order as long as you
 specify their names
   >>>    def foo(x,y,z): return(2*x,4*y,8*z)
   >>>    foo(2,3,4)
   (4,    12, 32)
   >>>    foo(z=4, y=2,
   x=3) (6, 8,     32)
   >>>    foo(-2, z=-4,
   y=-3)
   (-4,    -12, -32)
 Can be combined
  with defaults, too
   >>>    def
   foo(x=1,y=2,z=3):
Functions are first-class objects
Functions can be used as any
 other datatype, eg:
 • Arguments to function
 • Return values of functions
 • Assigned to variables
 • Parts of tuples, lists, etc
>>> def square(x): return x*x
>>> def applier(q, x): return q(x)
>>> applier(square, 7)
49
             Lambda Notation
 A lambda function is a function that can be defined
 without a name, and is often used for simple, one-
 time operations.
 lambda arguments : expression
The expression is executed and the result is
returned:
Example Add 10 to argument a, and return
the result:
x = lambda a : a + 10
print(x(5))                                 Ans
15
         Example: composition
Function composition is the way of combining two or more
functions in such a way that the output of one function
becomes the input of the second function and so on
# Function to add 2
# to a number
def add(x):
   return x + 2
                               Output:
# Function to multiply
# 2 to a number                     Adding 2 to 5 and multiplying the result
def multiply(x):                    with 2: 14
   return x * 2
# Printing the result of
# composition of add and
# multiply to add 2 to a number
# and then multiply by 2
print("Adding 2 to 5 and multiplying the
result with 2: ",
    multiply(add(5)))
Closure
• In Python, a closure is a powerful concept
  that allows a function to remember and
  access variables, even when the function is
  executed outside that scope.
• Closures are closely related to nested
  functions and are commonly used in
  functional programming, event handling and
  callbacks.
• A closure is created when a function (the
  inner function) is defined within another
  function (the outer function) and the inner
  function references variables from the outer
  function.
• Closures are useful when you need a
  function to retain state across multiple calls,
                      Example: closure
def fun(a):
  # Outer function that remembers the
value of 'a'
  def adder(b):
      # Inner function that adds 'b' to 'a'
      return a + b
  return adder # Returns the closure
# Create a closure that adds 10 to any
number
val = fun(10)
                                              Output
                                              15
# Use the closure
                                              30
print(val(5))
                                              In this example:
print(val(20))
                                              fun(10) creates a closure that remembers
                                              the value 10 and adds it to any number
                                              passed to the closure.
How Closures Work Internally?
  When a closure is created, Python internally
  stores a reference to the environment (variables in
  the enclosing scope) where the closure was
  defined. This allows the inner function to access
  those variables even after the outer function has
  completed.
  In simple terms, a closure “captures” the values
  from its surrounding scope and retains them for
  later use. This is what allows closures to
  remember values from their environment.
Map Function in Python
The map () function returns a map
object(which is an iterator) of the
results after applying the given
function to each item of a given
iterable (list, tuple, etc.).
Syntax: map(fun, iter)
Parameters:
fun: It is a function to which map
passes each element of given
iterable.
Example:
In this example, Python program showcases
the usage of the map function to double
each number in a given list by applying the
double function to each element, and then
printing the result as a list.
# Function to return double of n
def double(n):
  return n * 2
# Using map to double all numbers
numbers = [5, 6, 7, 8]
result = map(double, numbers)           Output
print(list(result))                     [10, 12, 14, 16]
Reduce Function in Python
The reduce function is used to apply a particular function
passed in its argument to all of the list elements
mentioned in the sequence passed along.This function
is defined in “functools” module.
Syntax: reduce(func, iterable[, initial])
Parameters:
fun: It is a function to execute on each element of the
iterable object
iter: It is iterable to be reduced
  Example :
In this example, we are using reduce() function from the
functools module to compute the product of elements in a given
list by continuously applying the lambda function that multiplies
two numbers together, resulting in the final product.
import functools
# Define a list of numbers
numbers = [1, 2, 3, 4]
# Use reduce to compute the product of list elements
product = functools.reduce(lambda x, y: x * y, numbers)
print("Product of list elements:", product)
Output
Product of list elements: 24
Filter Function in Python
The filter() method filters the given
sequence with the help of a function that
tests each element in the sequence to be
true or not.
Syntax: filter(function, sequence)
Parameters:
function: function that tests if each
element of a sequence is true or not.
sequence: sequence which needs to be
filtered, it can be sets, lists, tuples, or
containers of any iterators.
   Example :
In this example, we defines a function is_even to check whether a
number is even or not. Then, it applies the filter() function to a list of
numbers to extract only the even numbers, resulting in a list containing
only the even elements. Finally, it prints the list of even numbers.
# Define a function to check if a number is even
def is_even(n):
  return n % 2 == 0
# Define a list of numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Use filter to filter out even numbers
even_numbers = filter(is_even, numbers)
print("Even numbers:", list(even_numbers))
Output
Even numbers: [2, 4, 6, 8, 10]