We have been discussing Python and its versatility. Now is the time to understand another functionality of this powerful programming language: it enhances code efficiency and readability. Maintaining the modularity of your code logic while working on a production-level program is important.
Python Function definition allows the developers to achieve this by encapsulating the codes. On the other hand, lambda functions provide a compact way to define simple functions in Python.
In this guide, we will explore the syntaxes, usages, and best practices for both types of Python functions to build a solid foundation for leveraging these tools in your Python projects in the industry. Whether you want to break complex tasks into simpler functions or utilize lambda functions for concise operations, these methods will help you write efficient code.
To refresh your Python basic to advance, go through these –
A function in Python is a reusable block of code that performs a specific task depending on the program’s logic. They can take inputs (known as parameters or arguments), perform certain operations, and return outputs.
Functions are really helpful in organizing code, making it more readable, maintainable, and efficient in production.
The function syntax involves two things:
In this part, you’ll write a logic, including a docstring, using the `def` keyword.
def function_name(paramters):
"""
doc-string
"""
function logic (body)
return output
The above function does not return any output on its own. To print the output on the screen, you need to call the function using this syntax.
function_name(arguments)
Let’s explore an example of how to create a function.
Now, let’s create our first function, including a docstring.
# Function body
def is_even(num:int):
"""
Check if a number is even or odd.
Parameters:
num (int): The number to check.
Returns:
str: "even" for the even number and, "odd" if the number is odd.
"""
# Function logic
if type(num) == int:
if num % 2 == 0:
return "even"
else:
return "odd"
else:
return "Function needs an integer aruguement"
# Calling function
for i in range(1,11):
print(i, "is", is_even(i))
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
You can use `.__doc__` to access the docstring of your function (or any built-in function, which we have discussed here).
print(is_even.__doc__)
Check if a number is even or odd.
Parameters:
num (int): The number to check.
Returns:
str: "even" for the even number and, "odd" if the number is odd.
Programmers often confuse the parameter/s and the argument/s and use them interchangeably while speaking. But let’s understand the difference between them so that you never get into this dilemma.
Due to their versatility, Python as a programming languages allows its functions to accept different types of arguments, providing flexibility in how to call them.
The main types of arguments are:
Let’s understand them one by one:
def greet(name, message="Hello"):
return f"{message}, {name}!"
print(greet("Nikita"))
print(greet("Nikita", "Hi"))
Outputs
Hello, Nikita!
Hi, Nikita!
def add(a, b):
return a + b
print(add(2, 3))
Output
Outputs: 5
def greet(name, message):
return f"{message}, {name}!"
print(greet(message="Hello", name="Nikita"))
Output
Outputs: Hello, Nikita!
`*args` and `**kwargs` are special python keywords that are used to pass the variable length of arguments to function.
def sum_all(*args):
print(type(args), args)
return sum(args)
print(sum_all(1, 2, 3, 4))
Output
<class 'tuple'> (1, 2, 3, 4)
# 10
def print_details(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_details(name="Nikita", age=20)
Output
name: Alice
age: 30
Note: Keyword arguments mean that they contain a key-value pair, like a Python dictionary.
The order of the arguments matters while writing a function to get the proper output:
def function_name(parameter_name, *args, **kwargs):
"""
Logic
"""
There are several types of functions Python offers the developers, such as:
Function Type | Description | Example |
---|---|---|
Built-in Functions | Predefined functions available in Python. | print(), len(), type() |
User-Defined Functions | Functions created by the user to perform specific tasks. | def greet(name): |
Lambda Functions | Small, anonymous functions with a single expression. | lambda x, y: x + y |
Recursive Functions | Functions that call themselves to solve a problem. | def factorial(n): |
Higher-Order Functions | Functions that take other functions as arguments or return them. | map(), filter(), reduce() |
Generator Functions | Functions that return a sequence of values one at a time using yield. | def count_up_to(max): |
I know this is a very heavy statement if you’ve never heard it before, but let’s discuss it.
Functions in Python are entities that support all the operations generally available to other objects, such as lists, tuples, etc.
Being first-class citizens means functions in Python can:
This flexibility allows for powerful and dynamic programming.
By now, you may be excited to know about the function’s type() and id(). So, let’s code it to understand better:
def sum(num1, num2):
return num1 + num2
print(type(sum))
print(id(sum))
Output
<class 'function'>
134474514428928
Like other objects, this function also has a class of functions and an ID address where it is stored in memory.
You can also assign a function to a variable, allowing you to call the function using that variable.
x = sum
print(id(x))
x(3,9)
Output
134474514428928
12
Note: x will have the same address as sum.
You can also store functions in data structures like lists, dictionaries, etc., enabling dynamic function dispatch.
l1 = [sum, print, type]
l1[0](2,3)
# Calling function inside of a list
Output
5
Let’s store a function `sum` in a set to prove this. As set will never allow mutable datatypes.
s = {sum}
s
Output
{<function __main__.sum(num1, num2)>}
Since we got an output, this confirms that the set is the immutable data types.
You can also pass functions as arguments to other functions, enabling higher-order functions and callbacks.
def shout(text):
return text.upper()
def whisper(text):
return text.lower()
def greet(func, name):
return func(f"Hello, {name}!")
print(greet(shout, "Nikita")) # Outputs: HELLO, NIKITA!
print(greet(whisper, "Nikita")) # Outputs: hello, nikita
Output
HELLO, NIKITA!
hello, nikita
We will cover higher-order functions in detail later in this article. So, stay tuned until the end!
A function can also return other functions, allowing the creation of multiple functions or decorators.
def create_multiplier(n):
def multiplier(x):
return x * n
return multiplier
double = create_multiplier(2)
print(double(5)) # Outputs: 10
triple = create_multiplier(3)
print(triple(5)) # Outputs: 15
Outputs
10
15
Python functions offer 3 major advantages, such as
Also read: What are Functions in Python and How to Create Them?
A lambda function, also called an inline function is a small anonymous function. It can take any number of arguments, but can only have one-line expression. These functions are particularly useful for a short period.
Let’s check some examples:
# square a value
func = lambda x : x**2
func(5)
Output
25
# Subtracting a value
func = lambda x=0, y=0: x-y
func(5)
Output
5
# Odd or Even
func = lambda x : "even" if x%2==0 else "odd"
func(1418236418)
Output
'even'
Feature | Lambda Function | Normal Function |
---|---|---|
Definition Syntax | Defined using the lambda keyword | Defined using the def keyword |
Syntax Example | lambda x, y: x + y | def add(x, y):\n return x + y |
Function Name | Anonymous (no name) | Named function |
Use Case | Short, simple functions | Complex functions |
Return Statement | Implicit return (single expression) | Explicit return |
Readability | Less readable for complex logic | More readable |
Scoping | Limited to a single expression | Can contain multiple statements |
Decorators | Cannot be decorated | Can be decorated |
Docstrings | Cannot contain docstrings | Can contain docstrings |
Code Reusability | Typically used for short, throwaway functions | Reusable and maintainable code blocks |
Lambda functions do not exist independently. The best approach to using them is with higher-order functions (HOF) like map, filter, and reduce.
While these functions have a limited scope compared to regular functions, they can offer a succinct way to streamline your code, especially in sorting operations.
Also read: 15 Python Built-in Functions which You Should Know while learning Data Science
A higher-order function, commonly known as an HOF, can accept other functions as arguments, return functions, or both.
For instance, this is how you can use a HOF:
# HOF
def transform(lambda_func, list_of_elements):
output = []
for i in L:
output.append(f(i))
print(output)
L = [1, 2, 3, 4, 5]
# Calling function
transform(lambda x: x**2, L)
Output
[1, 4, 9, 16, 25]
The main function in this code snippet is to take a lambda function and a list of elements.
Note: As per the problem statement, you can apply any specific logic using this lambda function.
Now, let’s dive deep into the Types of HOFs.
Here are 3 HOF in Python:
It applies a given function to each item of an iterable (e.g., list, dictionary, tuple) and returns a list of the results.
For instance,
# Fetch names from a list of dict
people = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 35},
{"name": "David", "age": 40}
]
list(map(lambda person: person["name"], people))
Output
['Alice', 'Bob', 'Charlie', 'David']
It creates a list of elements for which a given function returns `True`, similar to any filter operation in different programming languages.
For instance,
# filter: fetch names of people older than 30
filtered_names = filter(lambda person: person["age"] > 30, people)
filtered_names_list = map(lambda person: person["name"], filtered_names)
print(list(filtered_names_list))
Output
['Charlie', 'David']
It applies a function cumulatively to the items of an iterable, reducing it to a single value.
For instance,
# reduce: concatenate all names into a single string
concatenated_names = reduce(lambda x, y: x + ", " + y, map(lambda person: person["name"], people))
print(concatenated_names)
Output
Alice, Bob, Charlie, David
Note: All of these functions expect a lambda function and an iterable.
To conclude this article on Python Functions Definition and Lambda Functions, I would say that if you aim to write robust and scalable code, it is really important to master both of these functionalities to work in real-life industries.
Additionally, this practice helps in writing cleaner code and enhances collaboration throughout the team, as other programmers can easily understand and use the predefined functions to reduce redundancy.
Ans. Function definitions, often referred to as normal functions in Python, allow programmers to encapsulate code into reusable blocks to promote modularity, enhance readability, and make it easier to debug.
Ans. Lambda functions, often referred to as anonymous or inline functions, provide a compact way to define simple functions as needed for a short period, such as in sorting operations or within higher-order functions like map(), filter(), and reduce().
Ans. Here’s the difference:
`map()`: Applies a given function to each item of an iterable and returns a list of the results.
`filter()`: creates a list of elements for which a given function returns `True`.
`reduce()`: Applies a function cumulatively to the items of an iterable, reducing it to a single value. Â