In Python, a higher-order function is a function that takes one or more functions as arguments, or returns a function as its result. These functions are used to build more complex functions and are an important tool for functional programming in Python.
Here are some examples of higher-order functions in Python:
- Map: The map() function takes a function and a sequence as arguments and returns a new sequence in which each element is the result of applying the function to the corresponding element of the original sequence. For example:
def square(x): return x ** 2 numbers = [1, 2, 3, 4, 5] squares = map(square, numbers) print(list(squares)) # Output: [1, 4, 9, 16, 25]
- Filter: The filter() function takes a function and a sequence as arguments and returns a new sequence containing only the elements for which the function returns True. For example:
def is_even(x): return x % 2 == 0 numbers = [1, 2, 3, 4, 5, 6] evens = filter(is_even, numbers) print(list(evens)) # Output: [2, 4, 6]
- Reduce: The reduce() function takes a function and a sequence as arguments and returns a single value that is the result of applying the function to the elements of the sequence, in a cumulative way. For example:
from functools import reduce def add(x, y): return x + y numbers = [1, 2, 3, 4, 5] total = reduce(add, numbers) print(total) # Output: 15
- Lambda Functions: Lambda functions are anonymous functions that can be defined on the fly and passed to other functions as arguments. For example:
numbers = [1, 2, 3, 4, 5] squares = map(lambda x: x ** 2, numbers) print(list(squares)) # Output: [1, 4, 9, 16, 25]
- Decorators: A decorator is a higher-order function that takes a function as input and returns a new function as output. The new function can add some behavior to the original function without modifying its code. For example:
def my_decorator(func): def wrapper(): print("Before the function is called.") func() print("After the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello() # Output: Before the function is called. Hello! After the function is called.
Properties of High order functions in Python:
Here are some of the key properties of higher-order functions in Python:
- Functions as arguments: Higher-order functions can take other functions as arguments. This allows functions to be more flexible and reusable, as the behavior of the function can be modified by passing in different functions as arguments.
- Functions as return values: Higher-order functions can also return functions as their result. This can be useful when creating functions that need to be customized based on the inputs or other factors.
- Anonymous functions: In Python, anonymous functions can be created using lambda expressions. These functions are not named and can be passed as arguments or returned by higher-order functions.
- Partial functions: Higher-order functions can also be used to create partial functions. This allows a function to be partially applied with arguments, creating a new function that takes fewer arguments than the original.
- Function composition: Higher-order functions can be used to compose multiple functions together. This can be useful for creating more complex functions that perform multiple operations on their input data.
Overall, higher-order functions are a powerful tool in Python that allow for more flexible and modular code. By taking advantage of these properties, developers can create more reusable, efficient, and maintainable code.
Method 1: Using functions as objects in High order function:
In Python, functions are first-class objects, which means they can be treated like any other object in the language. This means they can be passed as arguments to other functions and returned as values from functions. Here is an example of using functions as objects in a higher-order function:
def apply_function(func, arg): return func(arg) def square(x): return x ** 2 result = apply_function(square, 5) print(result) # Output: 25
In this example, we define a function called apply_function
that takes two arguments: func
and arg
. The func
argument is a function, and the arg
argument is the input value to be passed to the function. Inside the apply_function
function, we simply call func
with arg
as its argument and return the result.
We also define a function called square
that takes one argument and returns its square. We then pass square
and the value 5
to apply_function
, which calls square(5)
and returns the result, which is 25
.
This is a simple example, but it illustrates the basic idea of using functions as objects in higher-order functions. By passing functions as arguments to other functions, we can create more flexible and reusable code.
Method 2: Functions as a parameter for another function:
In Python, it is common to pass functions as parameters to another function. This is one of the key features of higher-order functions. Here is an example of a higher-order function that takes a function as a parameter:
def operate_on_list(func, lst): result = [] for item in lst: result.append(func(item)) return result def square(x): return x ** 2 numbers = [1, 2, 3, 4, 5] squared_numbers = operate_on_list(square, numbers) print(squared_numbers) # Output: [1, 4, 9, 16, 25]
In this example, we define a function called operate_on_list
that takes two arguments: func
and lst
. The func
argument is a function that will be applied to each element in the list lst
. Inside the function, we loop over each item in lst
, apply func
to it, and append the result to a new list called result
. Finally, we return the result
list.
We also define a function called square
that takes one argument and returns its square. We then pass square
and a list of numbers to operate_on_list
, which applies square
to each number in the list and returns a new list of the squared numbers.
This example demonstrates how functions can be passed as parameters to other functions to create more flexible and reusable code. By abstracting the operation that is applied to each element of the list into a separate function, we can easily change the behavior of operate_on_list
by passing in a different function.
Method 3: Returning function as a result in high order function:
In Python, higher-order functions can also return functions as their result. Here is an example of a higher-order function that returns a function:
def create_multiplier(x): def multiplier(y): return x * y return multiplier double = create_multiplier(2) triple = create_multiplier(3) print(double(5)) # Output: 10 print(triple(5)) # Output: 15
In this example, we define a function called create_multiplier
that takes one argument x
. Inside the function, we define another function called multiplier
that takes one argument y
. The multiplier
function returns the product of x
and y
.
Finally, the create_multiplier
function returns the multiplier
function. We then call create_multiplier
twice to create two new functions: double
and triple
. The double
function multiplies its input by 2, and the triple
function multiplies its input by 3.
We can then call double(5)
and triple(5)
to get the results 10 and 15, respectively.
This example demonstrates how higher-order functions can be used to create new functions that have specific behaviors. By returning a function from create_multiplier
, we can create new functions with different multipliers without having to define a separate function for each multiplier.
Method 4: Decorators as high order function:
Decorators are a common example of higher-order functions in Python. A decorator is a function that takes another function as its argument and returns a new function that wraps the original function with some additional functionality. Here is an example of a decorator:
def uppercase_decorator(func): def wrapper(text): original_result = func(text) modified_result = original_result.upper() return modified_result return wrapper @uppercase_decorator def greet(name): return f"Hello, {name}!" print(greet("John")) # Output: HELLO, JOHN!
In this example, we define a decorator function called uppercase_decorator
that takes another function func
as its argument. Inside the decorator function, we define a new function called wrapper
that takes one argument text
. The wrapper
function calls the original func
with the text
argument, stores the result in a variable called original_result
, converts the original_result
to uppercase, and returns the modified result.
We then use the @uppercase_decorator
syntax to apply the decorator to the greet
function. This means that when we call greet
, the uppercase_decorator
function will be called with greet
as its argument, and the returned function (wrapper
) will be used instead of the original greet
function.
When we call greet("John")
, the output will be "HELLO, JOHN!"
. This is because the uppercase_decorator
has modified the output of the original greet
function by converting it to uppercase.
This example demonstrates how decorators can be used to modify the behavior of functions without changing their code. By passing a function as an argument to a decorator, we can create a new function that has the same behavior as the original function with some additional functionality.