Nearby lessons

63 of 108

Python - Functions

Introduction to Functions

While writing programs, sometimes we need to write the same group of statements again and again.

Writing the same code repeatedly is not a good programming practice because it increases the size of the program and makes maintenance difficult.

Instead of rewriting the same statements multiple times, we can group them together into a single unit and use that unit whenever required.

This single unit is called a Function.

A function allows us to write the code once and execute it many times by simply calling the function.

Definition of Function

A Function is a group of related statements that performs a specific task.

Once a function is created, it can be called whenever required without rewriting the same code.

Real-Life Example

Suppose a school management system needs to print the following message many times:

Hello Students
Welcome to Python Class

Instead of writing these statements repeatedly, we can place them inside a function and call that function whenever needed.

Advantages of Functions

According to the tutorial, the main advantage of functions is Code Reusability.

Functions also provide several additional benefits.

  • Code Reusability.
  • Reduces duplicate code.
  • Improves readability.
  • Makes programs easier to maintain.
  • Reduces program size.
  • Makes debugging easier.
  • Improves modular programming.

Code Reusability

Code Reusability means writing the code once and using it many times.

Instead of copying the same statements into different parts of the program, we simply call the function.

This saves both time and effort.

Types of Functions

Python supports two types of functions.

  1. Built-in Functions
  2. User Defined Functions

1. Built-in Functions

Functions that are already available in Python are called Built-in Functions or Predefined Functions.

These functions are automatically available after installing Python.

We do not need to write their implementation.

Common Built-in Functions

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
6



30

2. User Defined Functions

Functions created by the programmer according to business requirements are called User Defined Functions.

These functions are written using the def keyword.

Syntax of User Defined Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
def Keyword used to define a function.
function_name Name of the function.
parameters Input values accepted by the function.
Doc String Description of the function.
statements Task performed by the function.
return Returns the result to the caller.

The def Keyword

The def keyword is used to create a User Defined Function.

Every function definition begins with the def keyword.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

First Function Program

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Good Morning

Hello Good Morning

Hello Good Morning

Understanding the Program

def wish():

Defines a function named wish().

print("Hello Good Morning")

This statement is executed whenever the function is called.

wish()

Calls the function.

Since the function is called three times, the message is printed three times.

Calling a Function

A function is executed only when it is called.

Simply defining a function does not execute it.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Welcome

Important Point

Merely defining a function does not execute it.

The function body is executed only when the function is called.

Difference Between Defining and Calling a Function

Defining Function Calling Function
Creates the function. Executes the function.
Uses def. Uses the function name followed by parentheses.
Executed only once. Can be executed any number of times.

Summary

Topic Description
Function Group of statements written as a single unit.
Main Advantage Code Reusability.
Built-in Functions Functions provided by Python.
User Defined Functions Functions created by the programmer.
def Keyword used to define a function.
Function Call Executes the function.

Important Notes

  • A function is a group of statements that performs a specific task.
  • The main advantage of functions is Code Reusability.
  • Python supports Built-in Functions and User Defined Functions.
  • Built-in Functions are available automatically with Python.
  • User Defined Functions are created by the programmer.
  • The def keyword is used to define a function.
  • Defining a function does not execute it.
  • A function executes only when it is called.
  • In other programming languages, functions may also be called methods, procedures, or subroutines.

Function Parameters and Arguments

Functions become more useful when they can accept input values.

These input values are called Arguments and they are received by the function through Parameters.

Parameters allow the same function to work with different values without changing the function code.

Parameters and Arguments

There are two important terms in Functions:

  • Formal Parameters
  • Actual Arguments

Formal Parameters

The variables declared inside the function definition are called Formal Parameters.

They receive values from the function call.

Actual Arguments

The values passed while calling a function are called Actual Arguments.

These values are copied into the formal parameters.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Durga

Hello Ravi

Hello Sunny

Explanation

In the above program:

  • name is the Formal Parameter.
  • "Durga", "Ravi" and "Sunny" are the Actual Arguments.
  • Every time the function is called, the argument value is assigned to the parameter.

Types of Arguments

Python supports different types of arguments.

  1. Positional Arguments
  2. Keyword Arguments
  3. Default Arguments
  4. Variable Length Arguments (covered in the next part)

1. Positional Arguments

In Positional Arguments, values are assigned to parameters according to their position.

The first argument is assigned to the first parameter, the second argument to the second parameter, and so on.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
80

Explanation

Parameter Argument
a 100
b 20

Since the arguments follow the correct order, the subtraction result is 80.

Changing the Position

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
-80

Explanation

Because positional arguments depend on their position, changing the order changes the result.

Rules of Positional Arguments

  • The number of arguments must match the number of parameters.
  • The order of arguments is very important.
  • Changing the order changes the result.

2. Keyword Arguments

In Keyword Arguments, values are passed using the parameter names.

Since the parameter name is specified, the order of arguments does not matter.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Example 1

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Durga Good Morning

Example 2

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Durga Good Morning

Explanation

Although the order of the arguments is changed, the output remains the same because values are assigned using parameter names.

Advantages of Keyword Arguments

  • Arguments can be supplied in any order.
  • Programs become easier to read.
  • The possibility of assigning incorrect values is reduced.

Mixing Positional and Keyword Arguments

Python allows positional and keyword arguments to be used together.

However, positional arguments must always come before keyword arguments.

Correct Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Durga Good Morning

Incorrect Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
SyntaxError:
Positional argument follows keyword argument

Important Rule

Positional arguments must always appear before keyword arguments.

A positional argument cannot appear after a keyword argument.

3. Default Arguments

Sometimes we want a parameter to have a default value.

If the caller does not supply a value, the default value is used automatically.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello Guest

Hello Durga

Hello Ravi

Explanation

During the first function call, no argument is passed.

Therefore, the default value "Guest" is used.

During the remaining calls, the supplied arguments replace the default value.

Rules for Default Arguments

  • Default parameters must be declared after non-default parameters.
  • A default value is used only when no argument is supplied.
  • If an argument is supplied, the default value is ignored.

Correct Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Incorrect Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
SyntaxError:
non-default argument follows default argument

Comparison of Argument Types

Argument Type Assignment Method Order Required
Positional Based on position. Yes
Keyword Based on parameter name. No
Default Uses predefined value if no argument is supplied. No

Summary

Topic Description
Formal Parameter Variable declared in the function definition.
Actual Argument Value passed during the function call.
Positional Argument Arguments assigned according to position.
Keyword Argument Arguments assigned using parameter names.
Default Argument Uses a predefined value when no argument is supplied.

Important Notes

  • Formal Parameters receive values from Actual Arguments.
  • Positional Arguments depend on the order of values.
  • Keyword Arguments depend on parameter names.
  • Keyword Arguments can be supplied in any order.
  • Positional Arguments must appear before Keyword Arguments.
  • Default Arguments provide default values for parameters.
  • Default parameters must always come after non-default parameters.
  • If a value is supplied, the default value is ignored.

Introduction to Variable Length Arguments

In the previous section, we learned that a function can receive parameters.

Normally, the number of arguments passed to a function must exactly match the number of formal parameters.

If the number of arguments is different, Python raises an error.

Sometimes, we do not know in advance how many arguments will be passed to a function.

In such situations, Python provides Variable Length Arguments.

Variable Length Arguments allow a function to accept any number of arguments.

Why Do We Need Variable Length Arguments?

Consider a program that calculates the sum of numbers.

Sometimes the user wants to add two numbers, sometimes three numbers, and sometimes ten numbers.

If we use normal parameters, we have to create different functions for every possible case.

This increases code duplication and makes the program difficult to maintain.

Variable Length Arguments solve this problem by allowing a single function to accept any number of values.

Problem with Normal Parameters

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

TypeError:
add() takes 2 positional arguments but 3 were given

Explanation

The function add() is defined with only two parameters:

a, b

The first function call passes two arguments, so it executes successfully.

The second function call passes three arguments.

Since the function expects only two arguments, Python raises a TypeError.

This is one of the biggest limitations of normal parameters.

Solution - Variable Length Arguments

Python provides the * (asterisk) operator to solve this problem.

The * operator allows a function to receive any number of positional arguments.

All the arguments are automatically collected into a single tuple.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
* Indicates Variable Length Positional Arguments.
args Stores all arguments inside a tuple.
function_name Name of the function.

Important Point

The name args is not a keyword.

It is only a naming convention.

You can use any valid variable name after the * operator.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
()

(10,)

(10, 20)

(10, 20, 30)

Understanding the Program

Whenever the function is called, Python collects all positional arguments into a tuple.

The tuple is stored inside the variable args.

The number of arguments can be zero, one, two, or any number.

Therefore, the same function works for every function call.

How Python Stores the Arguments

Function Call args Value
display() ()
display(10) (10,)
display(10,20) (10,20)
display(10,20,30) (10,20,30)

Advantages of *args

  • Accepts any number of positional arguments.
  • Removes the limitation of fixed parameters.
  • Reduces duplicate functions.
  • Improves code reusability.
  • Makes functions more flexible.

Real-World Applications

Variable Length Arguments are commonly used in:

  • Calculator applications.
  • Logging utilities.
  • Mathematical operations.
  • Data processing utilities.
  • Framework development.

Quick Summary

Concept Description
Normal Parameters Accept a fixed number of arguments.
Variable Length Arguments Accept any number of arguments.
*args Collects all positional arguments into a tuple.
Data Type of args Tuple

Important Notes

  • *args accepts any number of positional arguments.
  • All arguments are stored as a tuple.
  • args is only a variable name, not a keyword.
  • The variable name can be changed.
  • Variable Length Arguments remove the limitation of fixed parameters.
  • Functions become more flexible and reusable.

Working with *args

In the previous section, we learned that *args collects any number of positional arguments into a tuple.

Now let's understand how to work with *args by using different examples.

Since args is a tuple, we can perform all tuple operations on it such as:

  • Traversing
  • Indexing
  • Finding Length
  • Calculating Sum

Example 1 - Print All Arguments

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(10, 20, 30, 40)

('Python', 'Java', 'C++')

Explanation

All positional arguments are collected into a tuple.

The tuple is printed directly.

The number of arguments can be different in every function call.

Example 2 - Traversing *args

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30
40

Explanation

Since args is a tuple, we can traverse it by using a for loop.

Each argument is printed one by one.

Example 3 - Count Total Arguments

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Total Arguments = 0

Total Arguments = 1

Total Arguments = 2

Total Arguments = 5

Explanation

The built-in len() function returns the total number of elements stored in the tuple.

This allows us to determine how many arguments were passed to the function.

Example 4 - Calculate the Sum

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

60

150

Explanation

The parameter numbers stores all arguments as a tuple.

The sum() function calculates the total of all tuple elements.

Example 5 - Find Maximum Value

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

100

Explanation

The built-in max() function returns the largest value from the tuple.

Example 6 - Find Minimum Value

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10

50

Example 7 - Accept Different Data Types

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
100
Python
10.5
True

Explanation

*args can store values of different data types because tuples support heterogeneous elements.

How *args Works

Function Call Tuple Created
display() ()
display(10) (10,)
display(10,20) (10,20)
display(10,20,30) (10,20,30)
display(10,20,30,40) (10,20,30,40)

Advantages of *args

  • Accepts unlimited positional arguments.
  • Eliminates the need for multiple overloaded functions.
  • Reduces duplicate code.
  • Improves code reusability.
  • Makes functions flexible.
  • Useful when the number of inputs is unknown.

Real-World Applications

  • Calculator applications.
  • Shopping cart total calculation.
  • Statistical calculations.
  • Logging systems.
  • Data processing libraries.
  • Framework development.

Summary

Operation Description
Print Display all arguments.
Traversal Use a for loop.
Count Use len(args).
Sum Use sum(args).
Maximum Use max(args).
Minimum Use min(args).

Important Notes

  • *args stores all positional arguments in a tuple.
  • Since it is a tuple, all tuple operations are supported.
  • The number of arguments can vary for each function call.
  • The parameter name args can be replaced with any valid identifier.
  • len(), sum(), max(), and min() can be used directly with *args.
  • *args is commonly used in Python libraries and frameworks.

Combining Normal Parameters with *args

In the previous section, we learned that *args can accept any number of positional arguments.

Sometimes, a function requires one or more fixed parameters along with additional variable-length arguments.

Python allows us to combine Normal Parameters and *args in the same function.

The fixed values are received by the normal parameters, and all remaining positional arguments are collected into *args.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
parameter1 Receives the first positional argument.
parameter2 Receives the second positional argument.
*args Collects all remaining positional arguments into a tuple.

Example 1 - One Normal Parameter

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Name : Rahul
Marks : (80, 90, 95)

Name : Neha
Marks : (70, 75)

Explanation

The first argument is assigned to the normal parameter name.

All remaining arguments are collected into the tuple marks.

Example 2 - Two Normal Parameters

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Name : Rahul
Age : 20
Subjects : ('Python', 'Java', 'React')

Explanation

The first argument is assigned to name.

The second argument is assigned to age.

All remaining arguments are stored inside subjects as a tuple.

Example 3 - Sum of Remaining Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Addition of Numbers
Sum = 100

Another Example
Sum = 30

Explanation

The first argument is stored in title.

The remaining numeric values are collected into numbers.

The sum() function calculates the total of all values stored in numbers.

Rules for Combining Normal Parameters and *args

  • Normal parameters must appear before *args.
  • *args should be the last positional parameter.
  • Python first assigns values to the normal parameters.
  • All remaining positional arguments are stored in *args.

Correct Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
(30, 40, 50)

How Python Assigns Values

Argument Assigned To
10 a
20 b
30 args Tuple
40
50

Incorrect Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
TypeError:
missing required keyword-only argument: 'a'

Why Does This Error Occur?

After *args, every parameter becomes a keyword-only parameter.

Therefore, the parameter a must be supplied using its name.

It cannot receive a positional argument.

Correct Way

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(10, 20, 30)
40

Comparison Table

Feature Normal Parameter *args
Accepts One Value Multiple Values
Data Type Depends on Input Tuple
Position Before *args After Normal Parameters
Purpose Required Values Additional Values

Real-World Applications

  • Student management systems where a student has a fixed name but variable subjects.
  • Billing systems where the customer name is fixed but purchased items vary.
  • Employee systems where employee details are fixed but allowances vary.
  • Framework APIs that accept mandatory parameters along with optional values.

Summary

Concept Description
Normal Parameters Receive fixed positional arguments.
*args Receives all remaining positional arguments.
Order Normal parameters must come before *args.
Data Type of args Tuple.

Important Notes

  • Normal parameters receive fixed arguments.
  • *args receives all remaining positional arguments.
  • Python first fills the normal parameters.
  • The remaining positional arguments are stored in a tuple.
  • Parameters written after *args become keyword-only parameters.
  • The name args is only a convention and can be replaced with any valid identifier.

Introduction to **kwargs

In the previous sections, we learned about *args, which accepts any number of positional arguments.

Python also provides **kwargs, which accepts any number of keyword arguments.

Keyword arguments are passed using the syntax parameter=value.

All keyword arguments are automatically collected into a Dictionary.

Why Do We Need **kwargs?

Sometimes we do not know in advance how many keyword arguments will be passed to a function.

Instead of creating multiple parameters, we can use **kwargs.

This makes the function flexible and reusable.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
** Indicates Variable Length Keyword Arguments.
kwargs Stores all keyword arguments in a Dictionary.
function_name Name of the function.

Important Point

The name kwargs is not a Python keyword.

It is only a naming convention.

You may use any valid variable name after **.

Example 1 - Print Keyword Arguments

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
{}

{'name': 'Durga'}

{'name': 'Durga', 'age': 35}

{'name': 'Durga', 'age': 35, 'city': 'Hyderabad'}

Explanation

Each keyword argument is stored as a key-value pair inside the Dictionary kwargs.

The function can receive zero, one, or many keyword arguments.

Example 2 - Traversing **kwargs

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
name = Rahul
age = 20
course = Python

Explanation

Since kwargs is a Dictionary, we can use the items() method to traverse all key-value pairs.

Example 3 - Using Normal Parameters with **kwargs

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Name : Rahul

Details : {'age': 20, 'city': 'Delhi', 'course': 'Python'}

Explanation

The normal parameter name receives the first positional argument.

All keyword arguments are collected into the Dictionary details.

Rules for **kwargs

  • **kwargs accepts only keyword arguments.
  • All keyword arguments are stored in a Dictionary.
  • Keys represent parameter names.
  • Values represent the supplied values.
  • The variable name kwargs can be replaced with any valid identifier.

Difference Between *args and **kwargs

Feature *args **kwargs
Accepts Positional Arguments Keyword Arguments
Data Type Tuple Dictionary
Symbol * **
Access Method Loop through tuple Loop through Dictionary
Example fun(10,20,30) fun(a=10,b=20)

Comparison of Normal Parameters, *args and **kwargs

Feature Normal Parameter *args **kwargs
Accepts Fixed Arguments Variable Positional Arguments Variable Keyword Arguments
Data Type Depends on Value Tuple Dictionary
Flexibility Low High High

Real-World Applications

  • Configuration settings.
  • API development.
  • Framework development (Django, Flask, FastAPI).
  • Passing optional settings.
  • Database configuration.
  • Logging utilities.

Summary

Concept Description
**kwargs Accepts any number of keyword arguments.
Storage Dictionary.
Key Parameter Name.
Value Supplied Value.
Traversal Using items().

Important Notes

  • **kwargs accepts any number of keyword arguments.
  • All keyword arguments are stored in a Dictionary.
  • kwargs is not a keyword; it is only a variable name.
  • Dictionary methods like keys(), values(), and items() can be used with kwargs.
  • *args stores positional arguments in a Tuple.
  • **kwargs stores keyword arguments in a Dictionary.
  • Both *args and **kwargs make functions flexible and reusable.

Return Statement

When a function completes its execution, sometimes it needs to send a result back to the function caller.

To send the result from a function, Python provides the return statement.

The return statement terminates the execution of the function and transfers control back to the calling statement.

If a value is specified after the return keyword, that value is returned to the caller.

Why Do We Need the Return Statement?

Consider a function that adds two numbers.

If the function only prints the result, the result cannot be used elsewhere in the program.

If the function returns the result, it can be stored in a variable, used in calculations, or passed to another function.

Therefore, returning values makes functions more useful and reusable.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Statement Purpose
return value Returns the specified value to the caller.
return Terminates the function without returning any value.

Example 1 - Function Returning a Value

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

Explanation

The function receives two numbers.

It calculates their sum and returns the result.

The returned value is stored in the variable result.

Finally, the value is printed.

Example 2 - Returning an Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

100

Explanation

The expression n * n is evaluated first.

The calculated value is then returned to the caller.

Example 3 - Returning a String

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Welcome to Python

Example 4 - Returning a Boolean Value

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
True

False

Example 5 - Returning a List

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Red', 'Green', 'Blue']

Example 6 - Function Without Return Statement

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Hello

None

Explanation

The function prints the message.

Since there is no return statement, Python automatically returns None.

Therefore, the variable result stores None.

Example 7 - Empty Return Statement

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Start

Explanation

When Python encounters the return statement, the function immediately terminates.

The statement after return is never executed.

Flow of Return Statement

Step Action
1 Function is called.
2 Function executes its statements.
3 return sends the result back.
4 Function execution stops.
5 Control returns to the caller.

Difference Between print() and return

print() return
Displays output on the screen. Returns a value to the caller.
Does not terminate the function. Terminates the function immediately.
Cannot be reused directly. The returned value can be reused anywhere.
Mainly used for displaying information. Mainly used for sending results back.

Real-World Applications

  • Returning calculated values from mathematical functions.
  • Returning database query results.
  • Returning API responses.
  • Returning validation results.
  • Returning processed data from helper functions.

Summary

Concept Description
return value Returns a value to the caller.
return Terminates the function.
No return statement Python returns None.
After return Remaining statements are not executed.
Purpose Send results back to the caller.

Important Notes

  • The return statement sends a value back to the caller.
  • It immediately terminates the function.
  • A function can return numbers, strings, lists, tuples, dictionaries, Boolean values, or objects.
  • If no return statement is written, Python automatically returns None.
  • Statements written after return are never executed.
  • The returned value can be stored in a variable or passed to another function.
  • return is different from print(); print() displays output, whereas return sends data back to the caller.

Returning Multiple Values from a Function

In the previous section, we learned how a function can return a single value by using the return statement.

Python also allows a function to return multiple values.

This is one of the powerful features of Python because many programming languages can return only one value directly.

When multiple values are returned, Python automatically packs them into a Tuple.

Why Return Multiple Values?

Sometimes a function performs multiple calculations and needs to send several results back to the caller.

For example:

  • Returning addition, subtraction, multiplication and division together.
  • Returning student name, marks and grade.
  • Returning minimum and maximum values.
  • Returning multiple statistics from a dataset.

Instead of calling multiple functions, Python allows us to return all results together.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Important Point

Although multiple values appear to be returned, Python actually returns a single Tuple.

Python automatically performs Tuple Packing.

Example 1 - Returning Multiple Values

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(30, 10, 200, 2.0)

Explanation

The function returns four values.

Python automatically packs these values into a tuple.

Therefore, the variable result stores a tuple.

Tuple Packing

When multiple values are returned, Python automatically creates a tuple.

This process is called Tuple Packing.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(10, 20, 30)

Receiving Multiple Returned Values

Instead of storing the returned tuple in a single variable, we can receive each value into separate variables.

This process is called Tuple Unpacking.

Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Addition = 30

Subtraction = 10

Multiplication = 200

Division = 2.0

Explanation

The returned tuple contains four values.

Each value is automatically assigned to the corresponding variable.

This process is known as Tuple Unpacking.

Example 2 - Returning Student Information

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Rahul

90

A

Example 3 - Returning Minimum and Maximum Values

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Minimum = 10

Maximum = 80

Example 4 - Returning Different Data Types

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(101, 'Python', True, 95.5)

Example 5 - Returning a Tuple Explicitly

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(1, 2, 3)

Automatic Tuple Packing

Return Statement Python Stores As
return 10,20 (10,20)
return 10,20,30 (10,20,30)
return "A",100 ("A",100)
return True,50.5 (True,50.5)

Difference Between Single Return and Multiple Return

Single Return Multiple Return
Returns one value. Returns multiple values.
Any data type. Automatically packed into a tuple.
Stored in one variable. Can be stored in one variable or unpacked into multiple variables.

Real-World Applications

  • Returning multiple calculation results.
  • Returning database records.
  • Returning API response values.
  • Returning student information.
  • Returning minimum and maximum values.
  • Returning statistical information.

Summary

Concept Description
Multiple Return Return more than one value.
Tuple Packing Python automatically creates a tuple.
Tuple Unpacking Assign returned values to multiple variables.
Storage Tuple.
Advantage Return multiple results using one function.

Important Notes

  • Python supports returning multiple values from a function.
  • Multiple returned values are automatically packed into a tuple.
  • This automatic conversion is called Tuple Packing.
  • The returned tuple can be stored in a single variable.
  • It can also be unpacked into multiple variables.
  • The number of receiving variables should match the number of returned values.
  • Multiple return values make functions more reusable and efficient.

Introduction to Variables in Functions

Variables are used to store data in a program.

Depending on where a variable is declared, Python classifies variables into different types.

Python supports two types of variables:

  • Global Variables
  • Local Variables

Understanding the scope of variables is very important because it determines where a variable can be accessed and modified.

Function vs Module vs Library

Before learning Global and Local Variables, it is important to understand three related terms.

Term Description
Function A group of statements written together to perform a specific task.
Module A file that contains one or more functions.
Library A collection of multiple related modules.

Global Variables

The variables declared outside of every function are called Global Variables.

Global variables belong to the entire module.

Every function inside the same module can access global variables unless a local variable with the same name exists.

Characteristics of Global Variables

  • Declared outside all functions.
  • Accessible throughout the module.
  • Can be shared by multiple functions.
  • Remain available until the program finishes.

Program: Accessing a Global Variable

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
10

Understanding the Program

The variable a is declared outside every function.

Therefore, it becomes a Global Variable.

Both f1() and f2() can access the same variable.

No separate copy of the variable is created for each function.

Scope of Global Variables

Declared Outside Function? Accessible Inside Function? Accessible by Multiple Functions?
Yes Yes Yes

Local Variables

The variables declared inside a function are called Local Variables.

A local variable exists only while the function is executing.

After the function completes, the local variable is destroyed.

It cannot be accessed from outside the function in which it is declared.

Characteristics of Local Variables

  • Declared inside a function.
  • Accessible only inside that function.
  • Cannot be accessed from outside the function.
  • Created when the function starts executing.
  • Destroyed after the function finishes execution.

Program: Local Variable

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10

NameError:
name 'a' is not defined

Understanding the Program

The variable a is created inside f1().

Therefore, it is a Local Variable.

It is available only while f1() is executing.

When f2() tries to access it, Python cannot find the variable and raises a NameError.

Lifetime of a Local Variable

Event Local Variable
Function starts Created
Function executes Available
Function ends Destroyed

Difference Between Global and Local Variables

Global Variable Local Variable
Declared outside functions. Declared inside functions.
Accessible throughout the module. Accessible only inside its function.
Can be shared by multiple functions. Cannot be shared outside the function.
Exists throughout program execution. Exists only while the function executes.

Real-World Applications

  • Global variables are used for application-wide configuration settings.
  • Global variables can store constants shared by many functions.
  • Local variables are used for temporary calculations.
  • Loop counters and intermediate results are generally local variables.
  • Keeping temporary values local improves program safety and readability.

Quick Summary

Topic Description
Global Variable Declared outside a function.
Local Variable Declared inside a function.
Scope of Global Variable Entire module.
Scope of Local Variable Only inside the function.
Lifetime of Local Variable Until the function completes execution.

Important Notes

  • Python supports Global Variables and Local Variables.
  • Global variables are declared outside functions.
  • Local variables are declared inside functions.
  • Global variables can be accessed by all functions in the same module.
  • Local variables are available only within the function where they are declared.
  • A local variable is created when the function starts and destroyed when the function ends.
  • Attempting to access a local variable outside its function results in a NameError.

The global Keyword

In the previous section, we learned that a Global Variable can be accessed inside a function.

However, if we try to modify a Global Variable directly inside a function, Python creates a new Local Variable instead of modifying the Global Variable.

To modify a Global Variable inside a function, we must use the global keyword.

The global keyword tells Python that the variable belongs to the Global Scope and not to the Local Scope.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Keyword Purpose
global Allows a function to modify a Global Variable.

Example 1 - Accessing a Global Variable

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
10

Explanation

The variable a is declared outside the function.

Since the function only reads the variable, the global keyword is not required.

Example 2 - Modifying Without global

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
20
10

Explanation

The assignment a = 20 creates a new Local Variable.

The Global Variable remains unchanged.

Therefore, the function prints 20, but outside the function the value is still 10.

Example 3 - Modifying a Global Variable

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
20
20

Explanation

The statement global a informs Python that the variable belongs to the Global Scope.

Now the assignment updates the original Global Variable instead of creating a Local Variable.

Therefore, both statements print 20.

Example 4 - Multiple Functions Using global

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
3

Explanation

The Global Variable count is updated every time the function is called.

Since the same Global Variable is modified, the final value becomes 3.

The globals() Function

Python provides the built-in globals() function.

This function returns a Dictionary containing all Global Variables available in the current module.

The Dictionary keys represent variable names, and the values represent the corresponding Global Variable values.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Example 5 - Using globals()

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
{'a': 10, 'b': 20, ...}

Explanation

The globals() function returns a Dictionary.

Besides user-defined Global Variables, the Dictionary also contains several built-in objects created by Python.

For simplicity, only user-defined variables are shown in the sample output.

Example 6 - Accessing Global Variables Using globals()

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
100
200

Explanation

The globals() function returns a Dictionary.

Dictionary indexing can be used to access any Global Variable by its name.

Example 7 - Modifying Global Variable Using globals()

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
50

Explanation

Since globals() returns the Global Namespace Dictionary, changing its value updates the original Global Variable.

Difference Between global Keyword and globals()

global Keyword globals() Function
Used inside a function. Can be used anywhere.
Declares a variable as Global. Returns the Global Namespace Dictionary.
Mainly used to modify Global Variables. Used to view or access all Global Variables.
Keyword. Built-in Function.

Real-World Applications

  • Maintaining application-wide counters.
  • Updating global configuration values.
  • Managing shared application state.
  • Accessing global settings across multiple functions.
  • Debugging by inspecting the Global Namespace.

Summary

Concept Description
global Allows modification of Global Variables inside a function.
globals() Returns the Global Namespace Dictionary.
Without global A new Local Variable is created during assignment.
With global The original Global Variable is modified.

Important Notes

  • Reading a Global Variable inside a function does not require the global keyword.
  • Modifying a Global Variable inside a function requires the global keyword.
  • Without global, Python creates a new Local Variable when an assignment is made.
  • globals() returns a Dictionary containing all Global Variables.
  • Global Variables can be accessed using dictionary indexing on the result of globals().
  • global is a keyword, whereas globals() is a built-in function.
  • Excessive use of Global Variables can make programs difficult to maintain, so they should be used carefully.

Introduction to Recursive Functions

In the previous sections, we learned how one function can call another function.

Python also allows a function to call itself.

A function that calls itself is called a Recursive Function.

The process of a function calling itself repeatedly until a specific condition is satisfied is known as Recursion.

Recursion is a powerful programming technique used to solve problems that can be divided into smaller versions of the same problem.

Definition

A Recursive Function is a function that calls itself either directly or indirectly until a terminating condition is reached.

The terminating condition is called the Base Case.

Why Do We Need Recursion?

Many real-world problems are naturally recursive.

Instead of writing complicated loops, recursion provides a cleaner and easier solution.

It is especially useful when solving problems that involve repeated subdivision into smaller sub-problems.

Common examples include:

  • Factorial Calculation
  • Fibonacci Series
  • Tree Traversal
  • Directory/File Traversal
  • Binary Search
  • Tower of Hanoi

How Recursion Works

Every recursive function contains two important parts:

  1. Base Case
  2. Recursive Case

The Recursive Case keeps calling the function repeatedly.

The Base Case stops further recursive calls and prevents infinite recursion.

Components of a Recursive Function

Component Purpose
Base Case Stops the recursion.
Recursive Case Calls the function again.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

First Recursive Program

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Output

Explanation

The function display() calls itself continuously.

Since there is no Base Case, the recursive calls never stop.

Python keeps creating new function calls until the maximum recursion depth is exceeded.

Finally, Python raises a RecursionError.

Understanding Infinite Recursion

Infinite recursion occurs when a recursive function has no terminating condition.

Every function call creates another function call.

Eventually, Python runs out of available call stack space.

To prevent this situation, every recursive function must include a Base Case.

Example with Base Case

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
5
4
3
2
1

Understanding the Program

The function starts with the value 5.

Each recursive call decreases the value of n by 1.

When n becomes 0, the Base Case executes and recursion stops.

Dry Run

Function Call Output
display(5) 5
display(4) 4
display(3) 3
display(2) 2
display(1) 1
display(0) Stops

Flow of Recursive Function

Step Action
1 Function is called.
2 Base Case is checked.
3 If Base Case is false, the function calls itself.
4 Each recursive call receives a smaller problem.
5 When the Base Case becomes true, recursion stops.

Difference Between Normal Function and Recursive Function

Normal Function Recursive Function
Does not call itself. Calls itself.
Usually uses loops for repetition. Uses repeated function calls.
Generally easier for simple repetitive tasks. Better for problems that can be divided into smaller sub-problems.

Real-World Applications

  • Factorial calculation.
  • Fibonacci sequence.
  • Binary Search.
  • Tree Traversal.
  • Graph Traversal.
  • Directory and File System Traversal.
  • Tower of Hanoi.

Quick Summary

Concept Description
Recursive Function A function that calls itself.
Base Case Stops recursion.
Recursive Case Calls the function again.
Without Base Case RecursionError occurs.
Main Use Solving recursive problems.

Important Notes

  • A Recursive Function calls itself.
  • Every recursive function must contain a Base Case.
  • The Base Case prevents infinite recursion.
  • If no Base Case exists, Python raises RecursionError.
  • Each recursive call should reduce the problem size.
  • Recursive functions are widely used for mathematical and tree-based algorithms.

Recursive Program - Factorial of a Number

The Factorial of a positive integer is the product of all positive integers from 1 to that number.

Factorial is represented by the symbol !.

It is one of the most common examples used to understand Recursion because the problem can be divided into smaller versions of itself.

Factorial Formula

The mathematical formula for factorial is:

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Examples

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Recursive Logic

The recursive definition of factorial is:

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Base Case

The recursion must stop when the value becomes 0 or 1.

Both 0! and 1! are equal to 1.

Program - Factorial Using Recursion

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Sample Output

Program Explanation

The function receives a number from the user.

If the number becomes 0, the Base Case executes and returns 1.

Otherwise, the function calls itself with n-1.

Each recursive call multiplies the current number with the factorial of the next smaller number.

Finally, all recursive calls return one by one and the final factorial value is produced.

Step-by-Step Execution for factorial(5)

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Recursive Function Calls

Function Call Status
factorial(5) Calls factorial(4)
factorial(4) Calls factorial(3)
factorial(3) Calls factorial(2)
factorial(2) Calls factorial(1)
factorial(1) Calls factorial(0)
factorial(0) Returns 1 (Base Case)

Call Stack (Function Calling Phase)

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Call Stack (Returning Phase)

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Visual Representation

Recursive Call Returned Value
factorial(0) 1
factorial(1) 1
factorial(2) 2
factorial(3) 6
factorial(4) 24
factorial(5) 120

Dry Run

Step Operation
1 factorial(5) is called.
2 It calls factorial(4).
3 Each function keeps calling the next smaller value.
4 When factorial(0) is reached, 1 is returned.
5 Each pending function multiplies its value while returning.
6 The final answer becomes 120.

Important Points

  • Every recursive function must contain a Base Case.
  • The Base Case prevents infinite recursion.
  • Each recursive call should reduce the problem size.
  • The recursive calls are stored in the Call Stack.
  • After reaching the Base Case, the Call Stack starts returning values one by one.
  • The factorial program is one of the best examples for understanding recursion.

Advantages of Recursive Functions

Recursive functions provide an elegant and efficient solution for many problems that can be divided into smaller sub-problems.

Instead of writing long and complex iterative code, recursion often produces shorter and easier-to-understand programs.

Some important advantages of recursion are listed below.

  • Produces shorter and cleaner code.
  • Makes programs easier to understand for recursive problems.
  • Suitable for mathematical problems such as Factorial and Fibonacci.
  • Very useful for Tree Traversal and Graph Traversal.
  • Reduces the complexity of solving divide-and-conquer problems.
  • Used extensively in searching and sorting algorithms.
  • Improves readability for naturally recursive problems.

Disadvantages of Recursive Functions

Although recursion is powerful, it also has some limitations.

Each recursive function call creates a new stack frame in memory.

If recursion continues for many levels, more memory is consumed and the program becomes slower.

  • Consumes more memory because of the Call Stack.
  • Slower than loops for many simple problems.
  • Improper Base Case causes infinite recursion.
  • May generate RecursionError.
  • Debugging recursive functions is more difficult than loops.
  • Not suitable for every programming problem.

When Should We Use Recursion?

Recursion should be used only when it makes the solution simpler and more natural.

Some common situations where recursion is preferred are:

  • Factorial Calculation
  • Fibonacci Series
  • Tree Traversal
  • Directory Traversal
  • Binary Search
  • Depth First Search (DFS)
  • Tower of Hanoi
  • Merge Sort and Quick Sort

When Should We Avoid Recursion?

Recursion should generally be avoided when:

  • A simple loop can solve the problem easily.
  • The recursion depth may become very large.
  • Memory usage is an important concern.
  • Performance is more important than code simplicity.

Recursion vs Loop

Recursion Loop
Function calls itself. Repeats statements using loops.
Uses Call Stack. Does not create recursive stack frames.
Consumes more memory. Consumes less memory.
Usually slower. Usually faster.
Code is shorter for recursive problems. Code may become longer for recursive problems.
Needs a Base Case. Needs a Loop Condition.
Best for divide-and-conquer problems. Best for repetitive tasks.

Normal Function vs Recursive Function

Normal Function Recursive Function
Does not call itself. Calls itself.
Usually uses loops. Uses recursive calls.
Consumes less memory. Consumes more memory.
Easy to debug. Comparatively difficult to debug.
Suitable for simple iterative tasks. Suitable for recursive problems.

Real-World Applications of Recursion

Recursion is widely used in modern software development.

  • Binary Search Algorithms
  • Tree Traversal (Preorder, Inorder, Postorder)
  • Graph Traversal (DFS)
  • Merge Sort
  • Quick Sort
  • File and Directory Traversal
  • Artificial Intelligence Search Algorithms
  • Dynamic Programming Problems
  • Expression Evaluation
  • Compiler Design

Complete Chapter Summary

Topic Description
Recursive Function A function that calls itself.
Base Case Stops recursion.
Recursive Case Calls the function again.
Call Stack Stores pending recursive function calls.
Factorial Classic example of recursion.
Infinite Recursion Occurs when the Base Case is missing.
RecursionError Raised when recursion exceeds the maximum recursion depth.
Advantages Cleaner code for recursive problems.
Disadvantages Higher memory usage and slower execution.
Applications Trees, Graphs, Sorting, Searching, AI, File Systems.

Important Interview Questions

  1. What is a Recursive Function?
  2. What is the Base Case?
  3. Why is the Base Case necessary?
  4. What is Infinite Recursion?
  5. What is Call Stack?
  6. Explain the execution of the Factorial Program.
  7. Differentiate between Recursion and Loop.
  8. What are the advantages and disadvantages of recursion?
  9. When should recursion be preferred over loops?
  10. Explain RecursionError with an example.

Important Notes

  • A Recursive Function calls itself.
  • Every recursive function must contain a Base Case.
  • The Base Case prevents infinite recursion.
  • Recursive calls are managed using the Call Stack.
  • Each recursive call should reduce the problem size.
  • Without a Base Case, Python raises RecursionError.
  • Recursion generally consumes more memory than loops.
  • Loops are usually faster for simple repetitive tasks.
  • Recursion is ideal for divide-and-conquer algorithms.
  • Tree Traversal and Graph Traversal are common recursive applications.

Introduction to Lambda (Anonymous) Functions

In the previous sections, we learned how to create functions using the def keyword.

Python also provides another way to create functions called Lambda Functions.

A Lambda Function is a small anonymous function that can be created without using the def keyword.

These functions are generally used when a function is required only for a short period of time.

Because they do not have a function name, they are also called Anonymous Functions.

Definition

A Lambda Function is an anonymous function created using the lambda keyword.

It can have any number of parameters but can contain only one expression.

The value of that expression is automatically returned.

Why Do We Need Lambda Functions?

Sometimes we need a function only once in a program.

Creating a complete function using def for such small tasks increases the amount of code.

Lambda Functions provide a simple and compact way to write these small functions.

They are commonly used with built-in functions like:

  • map()
  • filter()
  • reduce()
  • sorted()

Characteristics of Lambda Functions

  • Created using the lambda keyword.
  • Do not have a function name.
  • Also called Anonymous Functions.
  • Can accept any number of parameters.
  • Can contain only one expression.
  • Automatically return the result of the expression.
  • Generally used for short and simple operations.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
lambda Keyword used to create an anonymous function.
arguments Input parameters for the function.
expression The expression whose result is automatically returned.

First Lambda Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

100

Explanation

The Lambda Function receives one parameter x.

The expression x * x is evaluated.

The calculated value is automatically returned.

Unlike a normal function, no explicit return statement is required.

Equivalent Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

100

Comparison

Both functions produce the same output.

The Lambda Function requires fewer lines of code.

It is suitable for simple operations.

Example - Addition

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

150

Example - Multiplication

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

200

Example - Convert to Uppercase

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
PYTHON

CODING

Lambda Function Flow

Step Action
1 Arguments are passed to the Lambda Function.
2 The expression is evaluated.
3 The result is automatically returned.

Limitations of Lambda Functions

  • Can contain only one expression.
  • Cannot contain multiple statements.
  • Cannot directly use loops like for or while.
  • Not suitable for writing complex business logic.
  • Mainly used for small operations.

Real-World Applications

  • Sorting custom objects.
  • Data transformation.
  • Filtering collections.
  • Data analysis.
  • Machine Learning preprocessing.
  • Using map(), filter(), and reduce().

Quick Summary

Concept Description
Lambda Function Anonymous function.
Keyword lambda
Name Not required.
Statements Only one expression.
Return Automatic.

Important Notes

  • Lambda Functions are also called Anonymous Functions.
  • They are created using the lambda keyword.
  • They can accept any number of parameters.
  • Only one expression is allowed inside a Lambda Function.
  • The expression result is returned automatically.
  • No explicit return statement is required.
  • Lambda Functions are commonly used with map(), filter(), and reduce().

Working with Lambda Functions

In the previous section, we learned how to create simple Lambda Functions.

In this section, we will learn how Lambda Functions work with multiple parameters, conditional expressions, and various practical examples.

Since Lambda Functions automatically return the value of a single expression, they are widely used for short calculations.

Lambda Function with Multiple Arguments

A Lambda Function can accept any number of arguments.

All arguments are separated by commas, just like normal function parameters.

Example 1 - Addition

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

150

Explanation

The Lambda Function accepts two parameters a and b.

The expression a + b is evaluated and the result is automatically returned.

Example 2 - Multiplication

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

600

Example 3 - Find Maximum

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
20

50

Explanation

The Lambda Function uses Python's conditional expression.

If a is greater than b, it returns a; otherwise, it returns b.

Example 4 - Find Minimum

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10

30

Lambda Function Returning Boolean Values

Lambda Functions can also return Boolean values.

This is useful when checking conditions.

Example 5 - Even Number

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
True

False

Example 6 - Positive Number

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
True

False

Lambda Function with Three Arguments

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
30

90

Lambda Function Returning Strings

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Welcome Rahul

Welcome Python

Lambda Function with String Operations

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
PYTHON

11

Nested Conditional Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
40

90

Flow of Lambda Function

Step Description
1 Arguments are passed to the Lambda Function.
2 The expression is evaluated.
3 The result is returned automatically.

Things to Remember

  • Lambda Functions can accept zero, one, or many arguments.
  • Only one expression is allowed.
  • The expression may contain arithmetic, logical, comparison, or conditional operators.
  • The evaluated result is returned automatically.
  • Complex business logic should be written using normal functions.

Common Use Cases

  • Simple mathematical calculations.
  • Conditional expressions.
  • Sorting collections.
  • Data transformation.
  • Filtering records.
  • Quick helper functions.

Summary

Feature Description
Multiple Arguments Supported.
Return Value Returned automatically.
Conditional Expression Supported.
Boolean Result Supported.
String Operations Supported.
Maximum Statements Only one expression.

Important Notes

  • Lambda Functions automatically return the expression result.
  • They can accept any number of parameters.
  • Conditional expressions can be used inside Lambda Functions.
  • Boolean values can be returned directly.
  • Lambda Functions are ideal for short and simple operations.
  • Multiple statements are not allowed inside a Lambda Function.

Lambda Function vs Normal Function

Python provides two ways to create functions:

  1. Normal Functions using the def keyword.
  2. Lambda (Anonymous) Functions using the lambda keyword.

Both perform the same task of executing reusable code, but they differ in syntax, complexity, and use cases.

Normal Functions are suitable for large programs, whereas Lambda Functions are ideal for short, single-expression operations.

Example 1 - Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

100

Example 2 - Lambda Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

100

Explanation

Both functions produce the same output.

The Lambda Function requires fewer lines of code because it automatically returns the expression result.

For simple operations, Lambda Functions make the code shorter and easier to read.

Normal Function vs Lambda Function

Normal Function Lambda Function
Created using the def keyword. Created using the lambda keyword.
Has a function name. Usually anonymous (no function name).
Can contain multiple statements. Can contain only one expression.
Requires an explicit return statement to return a value. Automatically returns the expression result.
Suitable for large and complex logic. Suitable for small and simple operations.
Supports loops, conditions, exception handling, and multiple statements. Cannot directly contain loops, multiple statements, or exception handling.
Easier to maintain for complex programs. Useful for quick, temporary helper functions.

Advantages of Lambda Functions

  • Short and concise syntax.
  • Requires fewer lines of code.
  • No explicit return statement is needed.
  • Ideal for one-time or temporary functions.
  • Works well with built-in functions like map(), filter(), and reduce().
  • Improves readability for simple operations.
  • Commonly used in Data Science and Machine Learning code.

Disadvantages of Lambda Functions

  • Only one expression is allowed.
  • Cannot contain multiple statements.
  • Cannot directly use loops such as for and while.
  • Not suitable for large business logic.
  • Can become difficult to read if the expression is too complex.
  • Less suitable for debugging than Normal Functions.

When Should You Use Lambda Functions?

Lambda Functions are recommended when:

  • A function is required only once.
  • The operation is very small.
  • Working with map(), filter(), or reduce().
  • Sorting collections using a custom key.
  • Writing short callback functions.

When Should You Use Normal Functions?

Normal Functions are recommended when:

  • The logic is complex.
  • Multiple statements are required.
  • The function needs loops or exception handling.
  • The function will be reused many times.
  • Better readability and maintainability are required.

Real-World Applications of Lambda Functions

  • Sorting objects using custom keys.
  • Data filtering.
  • Data transformation.
  • Machine Learning preprocessing.
  • Data Analysis with Pandas.
  • GUI callback functions.
  • Functional programming.

Complete Chapter Summary

Topic Description
Lambda Function An anonymous function created using the lambda keyword.
Anonymous Function A function without a predefined name.
Arguments Can accept any number of arguments.
Expression Only one expression is allowed.
Return Value Automatically returned.
Main Uses map(), filter(), reduce(), sorting, callbacks.
Best For Short and simple functions.
Avoid For Complex business logic.

Important Interview Questions

  1. What is a Lambda Function?
  2. Why is a Lambda Function called an Anonymous Function?
  3. What is the syntax of a Lambda Function?
  4. How many expressions are allowed inside a Lambda Function?
  5. Can Lambda Functions have multiple parameters?
  6. Differentiate between Normal Functions and Lambda Functions.
  7. What are the advantages of Lambda Functions?
  8. What are the disadvantages of Lambda Functions?
  9. Where are Lambda Functions commonly used?
  10. Why are Lambda Functions frequently used with map(), filter(), and reduce()?

Important Notes

  • Lambda Functions are anonymous functions.
  • They are created using the lambda keyword.
  • They can accept any number of arguments.
  • Only one expression is allowed.
  • The expression result is returned automatically.
  • No explicit return statement is required.
  • Lambda Functions are ideal for small operations.
  • Normal Functions are better for large and reusable code.
  • Lambda Functions are widely used in Functional Programming and Data Science.

Introduction to filter() Function

The filter() function is one of Python's built-in functions.

It is used to select elements from an iterable (such as a list, tuple, or set) based on a given condition.

Instead of modifying the original collection, filter() creates a new iterator that contains only the elements that satisfy the specified condition.

In Python, filter() is commonly used together with Lambda Functions to write short and efficient code.

Definition

The filter() function filters elements from an iterable by applying a function to each element.

If the function returns True, the element is included in the result.

If the function returns False, the element is discarded.

Why Do We Need filter()?

Suppose we have a list containing hundreds of numbers.

If we want only the even numbers, we would normally use a loop with an if statement.

The filter() function performs this task in a much shorter and cleaner way.

It helps improve code readability and reduces the amount of code.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Parameter Description
function A function that returns either True or False.
iterable The collection whose elements will be filtered.

Return Value

The filter() function returns a filter object.

This filter object is an iterator.

To display the filtered values, it is usually converted into a list, tuple, or set.

Program 1 - Simple filter() Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[25, 30]

Explanation

The Lambda Function checks whether each number is greater than 20.

If the condition is True, the element is selected.

Initially, filter() returns a filter object.

After converting it into a list using list(), the filtered values become visible.

Program 2 - Filtering Even Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30, 40]

Explanation

The Lambda Function checks whether the remainder after dividing by 2 is equal to 0.

If the condition is true, the number is included in the result.

Program 3 - Filtering Odd Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[15, 25, 35]

Program 4 - Using a Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30]

Explanation

Instead of using a Lambda Function, a Normal Function can also be passed to filter().

The function should always return True or False.

How filter() Works

Element Condition Included?
10 True ✔ Yes
15 False ✘ No
20 True ✔ Yes
25 False ✘ No
30 True ✔ Yes

Flow of filter() Function

Step Description
1 Read one element from the iterable.
2 Pass the element to the function.
3 If the function returns True, keep the element.
4 If the function returns False, discard the element.
5 Return the filtered iterator.

Advantages of filter()

  • Simple and readable code.
  • Reduces the need for loops.
  • Works efficiently with Lambda Functions.
  • Useful for selecting required data.
  • Returns an iterator, making it memory efficient.

Quick Summary

Concept Description
Function filter()
Purpose Select elements that satisfy a condition.
Returns Filter Object (Iterator)
Common Partner Lambda Function
Output Conversion list(), tuple(), set()

Important Notes

  • filter() is a built-in Python function.
  • It selects elements based on a condition.
  • The supplied function must return True or False.
  • It returns a filter object (iterator).
  • Convert the filter object using list(), tuple(), or set() to view the filtered elements.
  • It is commonly used with Lambda Functions.

More filter() Examples

In the previous section, we learned the basics of the filter() function.

In this section, we will explore more practical examples using different types of data.

These examples demonstrate how filter() can be used to filter numbers, strings, and other collections efficiently.

Program 1 - Filter Positive Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[20, 40, 50]

Explanation

The Lambda Function checks whether each number is greater than 0.

Only positive numbers satisfy the condition and are included in the result.

Program 2 - Filter Negative Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[-10, -30, -60]

Program 3 - Filter Numbers Greater Than 50

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[55, 70, 90]

Program 4 - Filter Numbers Divisible by 5

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[15, 20, 25, 35]

Program 5 - Filter Non-Empty Strings

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Rahul', 'Amit', 'Neha', 'Python']

Explanation

The Lambda Function checks whether the string is not empty.

Only non-empty strings are included in the final result.

Program 6 - Filter Names Starting with 'A'

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Amit', 'Ankit', 'Ajay']

Program 7 - Filter String Length Greater Than 5

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Python', 'JavaScript']

Program 8 - Filter Even Numbers from a Tuple

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(10, 20, 30)

Program 9 - Filter Values from a Set

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
{20, 25, 30}

Program 10 - Using filter() with None

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 'Python', True, 25]

Explanation

When None is passed as the first argument, filter() automatically removes all falsy values.

Falsy values include:

  • 0
  • False
  • None
  • Empty String ("")
  • Empty List
  • Empty Tuple
  • Empty Dictionary

Only truthy values remain in the final output.

Real-World Applications

  • Filtering active users from a database.
  • Selecting students who passed an examination.
  • Removing invalid records from datasets.
  • Filtering positive transactions.
  • Cleaning missing values during data preprocessing.
  • Filtering API response data.
  • Filtering files based on extensions.

Advantages of filter()

  • Produces clean and readable code.
  • Reduces the need for manual loops.
  • Works efficiently with Lambda Functions.
  • Supports all iterable objects.
  • Returns an iterator, making it memory efficient.
  • Useful for data filtering tasks.

Complete Summary

Feature Description
Function filter()
Purpose Select elements that satisfy a condition.
Input Function + Iterable
Return Type Filter Object (Iterator)
Works With List, Tuple, Set, String, etc.
Common Partner Lambda Function

Important Interview Questions

  1. What is the purpose of the filter() function?
  2. What does filter() return?
  3. Why is list() commonly used with filter()?
  4. Can filter() work with Normal Functions?
  5. Can filter() work with Lambda Functions?
  6. What happens when None is passed to filter()?
  7. Which iterable objects are supported by filter()?
  8. Differentiate between filter() and loops.

Important Notes

  • filter() returns only elements that satisfy a condition.
  • The filtering function must return True or False.
  • It returns a filter object (iterator).
  • Use list(), tuple(), or set() to display the filtered values.
  • filter(None, iterable) removes all falsy values from the iterable.
  • filter() works with all iterable objects such as lists, tuples, sets, and strings.
  • It is widely used in Data Analysis, Machine Learning, and Functional Programming.

Introduction to map() Function

The map() function is one of Python's built-in functions.

It is used to apply a function to every element of an iterable such as a list, tuple, set, or string.

Unlike filter(), which selects elements based on a condition, map() transforms every element and returns the modified values.

The original iterable remains unchanged because map() creates a new iterator containing the transformed elements.

In Python, map() is commonly used together with Lambda Functions to write concise and efficient code.

Definition

The map() function applies a specified function to each element of an iterable.

The transformed elements are returned as a map object.

Why Do We Need map()?

Suppose we have a list of numbers and want to calculate the square of every number.

Normally, we would use a loop and create another list.

The map() function performs this task in a cleaner and shorter way.

It reduces the amount of code and improves readability.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Parameter Description
function The function that will be applied to every element.
iterable The collection whose elements will be transformed.

Return Value

The map() function returns a map object.

The map object is an iterator.

To display the transformed values, it is generally converted into a list, tuple, or set.

Program 1 - First map() Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[2, 4, 6, 8, 10]

Explanation

The Lambda Function multiplies every number by 2.

Initially, map() returns a map object.

Using list(), the transformed values become visible.

Program 2 - Square of Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 4, 9, 16, 25]

Program 3 - Cube of Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 8, 27, 64, 125]

Program 4 - Using a Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[4, 16, 36, 64]

Explanation

Instead of using a Lambda Function, a Normal Function can also be passed to map().

The function is applied to every element of the iterable one by one.

Program 5 - Convert Strings to Uppercase

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['PYTHON', 'JAVA', 'REACT', 'NODE']

Program 6 - Find Length of Strings

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[6, 4, 5, 10]

How map() Works

Original Element Transformation New Value
1 x × 2 2
2 x × 2 4
3 x × 2 6
4 x × 2 8
5 x × 2 10

Flow of map() Function

Step Description
1 Read one element from the iterable.
2 Pass the element to the function.
3 Transform the element.
4 Store the transformed value.
5 Return a map object.

Advantages of map()

  • Produces clean and concise code.
  • Eliminates the need for manual loops.
  • Works efficiently with Lambda Functions.
  • Does not modify the original iterable.
  • Returns an iterator, making it memory efficient.
  • Useful for transforming large collections of data.

Quick Summary

Concept Description
Function map()
Purpose Transform elements of an iterable.
Returns Map Object (Iterator)
Common Partner Lambda Function
Output Conversion list(), tuple(), set()

Important Notes

  • map() is a built-in Python function.
  • It applies a function to every element of an iterable.
  • It returns a map object (iterator).
  • The original iterable is not modified.
  • Convert the map object using list(), tuple(), or set() to display the transformed values.
  • Both Lambda Functions and Normal Functions can be used with map().

More map() Examples

In the previous section, we learned the basics of the map() function.

In this section, we will explore more practical examples using numbers, strings, and multiple iterables.

These examples demonstrate how map() can efficiently transform data without modifying the original iterable.

Program 1 - Add 10 to Every Number

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[15, 20, 25, 30, 35]

Explanation

The Lambda Function adds 10 to every element.

The transformed values are returned as a new iterator.

Program 2 - Convert Strings to Lowercase

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['python', 'java', 'react', 'node']

Program 3 - Capitalize First Letter

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Rahul', 'Amit', 'Neha', 'Pooja']

Program 4 - Convert Integers to Strings

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['10', '20', '30', '40']

Explanation

The built-in str() function is passed directly to map().

Each integer is converted into its string representation.

Program 5 - Find Length of Each String

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[5, 7, 4, 9]

Program 6 - Square of Tuple Elements

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
(4, 16, 36, 64)

Program 7 - Multiply Elements from Two Lists

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 40, 90, 160]

Explanation

map() can accept multiple iterables.

The Lambda Function receives one element from each iterable at the same position.

The corresponding elements are multiplied together.

Program 8 - Add Elements of Two Lists

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[11, 22, 33]

Program 9 - Convert List of Strings to Integers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30, 40]

Program 10 - Remove Extra Spaces

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Rahul', 'Amit', 'Neha', 'Pooja']

Working with Multiple Iterables

One of the important features of map() is that it can process multiple iterables simultaneously.

The supplied function receives one value from each iterable during every iteration.

If the iterables have different lengths, processing stops when the shortest iterable is exhausted.

Flow of map() with Multiple Iterables

List 1 List 2 Lambda Result
1 10 10
2 20 40
3 30 90
4 40 160

Real-World Applications

  • Converting data types.
  • Formatting user input.
  • Cleaning datasets before analysis.
  • Performing mathematical calculations.
  • Transforming API response data.
  • Data preprocessing for Machine Learning.
  • Applying the same operation to every record.

Advantages of map()

  • Produces concise and readable code.
  • Eliminates manual loops.
  • Works efficiently with Lambda Functions.
  • Supports multiple iterables.
  • Returns an iterator, making it memory efficient.
  • Does not modify the original iterable.

Complete Summary

Feature Description
Function map()
Purpose Transform every element of an iterable.
Input Function + One or More Iterables
Return Type Map Object (Iterator)
Supports Multiple Iterables
Common Partner Lambda Function

Important Interview Questions

  1. What is the purpose of the map() function?
  2. What does map() return?
  3. Can map() work with Normal Functions?
  4. Can map() process multiple iterables?
  5. What happens if multiple iterables have different lengths?
  6. How is map() different from filter()?
  7. Can built-in functions like str() and len() be passed to map()?
  8. Why is map() widely used in Data Science?

Important Notes

  • map() transforms every element of an iterable.
  • It returns a map object (iterator).
  • Use list(), tuple(), or set() to display the transformed values.
  • It supports one or more iterables.
  • If multiple iterables are supplied, processing stops when the shortest iterable ends.
  • Both Lambda Functions and Normal Functions can be used with map().
  • map() is widely used in Functional Programming, Data Analysis, and Machine Learning.

Introduction to reduce() Function

The reduce() function is used to reduce an entire iterable into a single value.

Unlike map(), which transforms every element, and filter(), which selects specific elements, reduce() repeatedly combines the elements of an iterable until only one final result remains.

The reduce() function is not a built-in function in Python 3.

It is available inside the functools module.

Definition

The reduce() function repeatedly applies a specified function to the elements of an iterable and produces a single final value.

Each iteration combines two values into one until all elements have been processed.

Why Do We Need reduce()?

Suppose we have a list of numbers.

If we want to calculate the total sum or product of all numbers, we normally use a loop.

The reduce() function performs this operation with very little code.

It is especially useful for cumulative calculations.

Importing reduce()

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Explanation

Since Python 3, reduce() belongs to the functools module.

Therefore, it must be imported before it can be used.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Parameter Description
function Function that combines two values.
iterable Collection whose values are processed.
initializer Optional starting value for the reduction.

Return Value

The reduce() function returns a single value.

This value is the final result after processing all elements of the iterable.

Program 1 - First reduce() Example

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
100

Explanation

The Lambda Function adds two values together.

The first two elements are added, then the result is added to the next element.

This process continues until every element has been processed.

The final result is 100.

Step-by-Step Execution

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Program 2 - Product of Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
120

Step-by-Step Execution

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Program 3 - Using a Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
50

Explanation

Instead of using a Lambda Function, a Normal Function can also be supplied to reduce().

The function always receives two arguments.

The returned value becomes the first argument for the next iteration.

Program 4 - Using an Initializer

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
160

Explanation

The initializer provides the starting value.

The reduction begins with 100.

Calculation:

100 + 10 = 110
110 + 20 = 130
130 + 30 = 160
        

How reduce() Works

Iteration Current Values Result
1 10, 20 30
2 30, 30 60
3 60, 40 100

Flow of reduce() Function

Step Description
1 Take the first two elements.
2 Apply the supplied function.
3 Store the returned result.
4 Combine the result with the next element.
5 Repeat until all elements are processed.
6 Return one final value.

Advantages of reduce()

  • Produces clean and compact code.
  • Ideal for cumulative calculations.
  • Works efficiently with Lambda Functions.
  • Returns a single final value.
  • Useful for mathematical operations.

Quick Summary

Concept Description
Function reduce()
Module functools
Purpose Reduce all elements into one value.
Returns Single Value
Common Partner Lambda Function

Important Notes

  • reduce() belongs to the functools module.
  • It must be imported before use.
  • It repeatedly combines iterable elements.
  • The supplied function always receives two arguments.
  • The final result is a single value.
  • An optional initializer can be supplied as the third argument.
  • Both Lambda Functions and Normal Functions can be used with reduce().

More reduce() Examples

In the previous section, we learned the basics of the reduce() function.

In this section, we will solve more practical examples using reduce().

These examples demonstrate how multiple values are repeatedly combined into a single final result.

Program 1 - Find Sum of Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
150

Explanation

The Lambda Function adds two numbers at a time.

The intermediate result becomes the first argument for the next iteration until a single final value remains.

Step-by-Step Execution

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Program 2 - Find Product of Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
120

Step-by-Step Execution

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Program 3 - Find Maximum Number

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
80

Explanation

The Lambda Function compares two values.

The larger value is carried forward to the next comparison.

Finally, the largest value is returned.

Program 4 - Find Minimum Number

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
15

Program 5 - Concatenate Strings

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Python is Awesome

Program 6 - Find Longest String

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Programming

Program 7 - Sum with Initializer

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
160

Explanation

The reduction starts with the initializer value 100.

Then every element of the iterable is added one by one.

Program 8 - Product with Initializer

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
240

Step-by-Step Execution

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Real-World Applications of reduce()

  • Finding the total sales amount.
  • Calculating total marks.
  • Finding maximum and minimum values.
  • Computing products of numbers.
  • String concatenation.
  • Financial calculations.
  • Data aggregation in Data Science.
  • Machine Learning preprocessing.

Advantages of reduce()

  • Produces short and readable code.
  • Ideal for cumulative calculations.
  • Works efficiently with Lambda Functions.
  • Returns a single final value.
  • Supports an optional initializer.
  • Useful in Functional Programming.

Complete Summary

Feature Description
Function reduce()
Module functools
Purpose Reduce all iterable elements into one value.
Return Type Single Value
Supports Initializer Yes
Common Partner Lambda Function

Comparison - filter(), map(), reduce()

Function Purpose Returns
filter() Select elements based on a condition. Filter Object
map() Transform every element. Map Object
reduce() Combine all elements into one value. Single Value

Important Interview Questions

  1. What is the purpose of reduce()?
  2. Which module contains the reduce() function?
  3. What does reduce() return?
  4. How many arguments does the supplied function receive?
  5. What is the purpose of the initializer?
  6. Can Normal Functions be used with reduce()?
  7. Differentiate between filter(), map(), and reduce().
  8. Where is reduce() commonly used in real-world applications?

Important Notes

  • reduce() belongs to the functools module.
  • It reduces an iterable to a single value.
  • The supplied function always receives two arguments.
  • The result of one iteration becomes the first argument of the next iteration.
  • An initializer provides the starting value for the reduction.
  • Both Lambda Functions and Normal Functions can be used with reduce().
  • reduce() is commonly used for aggregation, mathematical calculations, and functional programming.

Introduction

Python provides three powerful functional programming utilities:

  • filter()
  • map()
  • reduce()

These functions are commonly used together with Lambda Functions to write short, readable, and efficient code.

Although all three functions work with iterables, each one serves a different purpose.

Quick Overview

Function Main Purpose
filter() Select elements that satisfy a condition.
map() Transform every element.
reduce() Combine all elements into a single value.

Comparison - filter() vs map() vs reduce()

Feature filter() map() reduce()
Purpose Select elements Transform elements Combine elements
Input Function + Iterable Function + One or More Iterables Function + Iterable
Output Filter Object Map Object Single Value
Works with Lambda Yes Yes Yes
Works with Normal Function Yes Yes Yes
Returns Iterator Yes Yes No
Returns Single Value No No Yes
Memory Efficient Yes Yes Yes
Main Use Filtering Data Data Transformation Aggregation

When Should You Use Each Function?

Situation Recommended Function
Select even numbers filter()
Select students who passed filter()
Convert names to uppercase map()
Calculate square of every number map()
Find total marks reduce()
Find product of numbers reduce()
Find largest value reduce()

Advantages

filter()

  • Selects only required elements.
  • Produces cleaner code.
  • Memory efficient.

map()

  • Transforms every element.
  • Reduces manual loops.
  • Supports multiple iterables.

reduce()

  • Produces one final result.
  • Ideal for aggregation.
  • Useful for mathematical calculations.

Disadvantages

Function Disadvantages
filter() Only selects elements; cannot transform them.
map() Cannot directly filter unwanted elements.
reduce() May reduce readability for beginners when used with complex expressions.

Real-World Applications

Application Function Used
Filter active users filter()
Remove invalid records filter()
Convert currencies map()
Convert temperatures map()
Total sales calculation reduce()
Payroll calculation reduce()
Data preprocessing All Three
Machine Learning All Three

Complete Chapter Summary

Concept Description
filter() Selects elements that satisfy a condition.
map() Transforms every element.
reduce() Combines iterable elements into one value.
Lambda Function Commonly used with all three functions.
Iterator filter() and map() return iterators.
Single Value reduce() returns one final value.
Module reduce() is available in the functools module.

Important Interview Questions

  1. Differentiate between filter(), map(), and reduce().
  2. What does each function return?
  3. Which module contains reduce()?
  4. Can all three functions work with Lambda Functions?
  5. Can all three functions work with Normal Functions?
  6. Which function returns a single value?
  7. Which function supports multiple iterables?
  8. When should filter() be preferred over map()?
  9. Explain a real-world use case for each function.
  10. What are the advantages of Functional Programming in Python?

Important Notes

  • filter() selects elements based on a condition.
  • map() transforms every element.
  • reduce() combines all elements into one final value.
  • filter() and map() return iterators.
  • reduce() returns a single value.
  • reduce() must be imported from the functools module.
  • All three functions work with Lambda Functions.
  • All three functions also support Normal Functions.
  • These functions are widely used in Functional Programming, Data Analysis, Artificial Intelligence, and Machine Learning.

Introduction to Generator Functions

In Python, a Generator Function is a special type of function that generates values one at a time instead of returning all values at once.

A Normal Function uses the return statement to return a value and terminate the function.

A Generator Function uses the yield keyword to produce a value and temporarily pause its execution.

When the Generator Function is called again, it continues execution from the point where it was previously paused.

This makes Generator Functions very useful when working with large amounts of data because they generate values only when required.

What is a Generator Function?

A Generator Function is a function that uses the yield keyword instead of the normal return statement to produce a sequence of values.

When a Generator Function is called, it does not immediately execute the complete function.

Instead, it returns a special object called a Generator Object.

The values from the Generator Object can be retrieved one at a time.

Why Do We Need Generator Functions?

Suppose we need to process millions of records.

If we store all records inside a list, the complete list must be stored in memory.

This can consume a large amount of memory.

A Generator Function solves this problem by generating one value at a time.

Therefore, Generator Functions are useful when:

  • Working with large datasets.
  • Reading large files.
  • Generating large sequences of numbers.
  • Processing streaming data.
  • Reducing memory consumption.
  • Generating values only when they are required.

The yield Keyword

The yield keyword is the most important part of a Generator Function.

It is similar to the return statement because both can send a value back to the caller.

However, there is an important difference.

The return statement terminates the function completely.

The yield statement pauses the function and saves its current state.

When the next value is requested, execution continues from the statement immediately after the previous yield.

Syntax of Generator Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

First Generator Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Explanation

The function display() contains three yield statements.

Because the function contains yield, Python automatically treats it as a Generator Function.

When display() is called, the function does not return all three values immediately.

Instead, it returns a Generator Object.

The exact memory address displayed in the Generator Object may be different each time the program runs.

Generator Object

A Generator Object represents the sequence of values produced by a Generator Function.

The Generator Object is also an iterator.

Therefore, we can retrieve values from it using:

  • The next() function.
  • A for loop.

Generator values are produced only when requested. This behaviour is known as Lazy Evaluation.

Using next() with Generator

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30

Explanation of next()

The first call to next(result) starts the Generator Function.

Execution continues until the first yield statement is reached.

The value 10 is produced and the function pauses.

The second call to next(result) continues execution from the previous position.

The value 20 is produced and the function pauses again.

The third call produces 30.

Step-by-Step Execution

Function Call Action Result
display() Creates Generator Object No value generated yet
First next() Executes until first yield 10
Second next() Continues until second yield 20
Third next() Continues until third yield 30

What Happens After All Values Are Generated?

After all values have been generated, calling next() again raises a StopIteration exception.

Example - StopIteration

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20

StopIteration

Explanation

The Generator Function contains only two yield statements.

The first two calls to next() return 10 and 20.

After that, no more values are available.

Therefore, the third call to next() raises StopIteration.

Using Generator with for Loop

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30

Explanation

A for loop automatically retrieves values from the Generator Object one at a time.

It internally handles the StopIteration exception.

Therefore, using a for loop is often easier than manually calling next().

Normal Function vs Generator Function

Normal Function Generator Function
Uses return. Uses yield.
Returns a value and terminates. Produces a value and pauses.
Does not preserve execution state after returning. Preserves execution state between yields.
Normally executes when called. Calling it creates a Generator Object; execution starts when iteration begins.
Usually returns the complete result. Generates values one at a time.
May require more memory when returning large collections. Memory efficient for large sequences.

return vs yield

return yield
Used in Normal Functions. Used in Generator Functions.
Terminates the function. Pauses the function.
Returns a value directly. Produces a value when requested.
Function state is not resumed after returning. Function state is preserved and execution can continue.

How Generator Function Works

Step Description
1 A Generator Function is defined using one or more yield statements.
2 Calling the function creates a Generator Object.
3 The first value is requested using next() or iteration.
4 The function executes until it reaches yield.
5 The value is produced and execution pauses.
6 The next request resumes execution from the previous position.
7 When the function finishes, iteration stops.

Advantages of Generator Functions

  • Memory efficient.
  • Generates values only when required.
  • Useful for processing large datasets.
  • Suitable for large or potentially infinite sequences.
  • Supports lazy evaluation.
  • Preserves the function state between values.

Quick Summary

Concept Description
Generator Function A special function that generates values one at a time.
Keyword yield
Return Type Generator Object
next() Retrieves the next generated value.
Lazy Evaluation Values are generated only when requested.
StopIteration Indicates that no more values are available.
Main Advantage Memory efficiency.

Important Notes

  • A Generator Function uses the yield keyword.
  • Calling a Generator Function returns a Generator Object.
  • The function body begins execution when iteration starts, such as with next() or a for loop.
  • yield pauses execution and preserves the current state.
  • The next request resumes execution from where it was paused.
  • Generators produce values one at a time.
  • Generators support lazy evaluation.
  • Calling next() after all values are exhausted raises StopIteration.
  • A for loop automatically handles StopIteration.
  • Generators are useful when working with large amounts of data.

Working with Generator Functions

In the previous section, we learned the basics of Generator Functions and the yield keyword.

In this section, we will learn how to work with Generator Functions using multiple yield statements, the next() function, for loops, parameters, and different number sequences.

Generator Functions generate values one at a time and preserve their execution state between each generated value.

Multiple yield Statements

A Generator Function can contain multiple yield statements.

Each yield produces one value and temporarily pauses the function.

When the next value is requested, execution continues from the statement immediately after the previous yield.

Program 1 - Multiple yield Statements

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30
40

Explanation

The function contains four yield statements.

The first call to next() produces 10.

The second call continues from the previous position and produces 20.

The same process continues until all values are generated.

Program 2 - Understanding Pause and Resume

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Start
10
After First Yield
20
After Second Yield
30

Explanation

When the first next() is called, the function starts execution.

It prints Start and reaches yield 10.

The value 10 is produced and the function pauses.

When the second next() is called, execution resumes after yield 10.

It prints After First Yield and produces 20.

The third next() resumes the function again and produces 30.

Using Generator Function with for Loop

A Generator Object is iterable.

Therefore, it can be directly used with a for loop.

The for loop automatically requests each value and stops when the Generator is exhausted.

Program 3 - Generator with for Loop

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30
40

Explanation

The for loop automatically retrieves each value from the Generator.

There is no need to manually call next().

When all values are generated, the loop automatically stops.

Generator Function with Parameters

Just like Normal Functions, Generator Functions can also accept parameters.

The parameter values can be used to control which values the Generator produces.

Program 4 - Generator with Parameter

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
2
3
4
5

Explanation

The Generator Function receives n as a parameter.

The variable i starts from 1.

Each iteration produces the current value of i.

After producing the value, the function pauses.

When the next value is requested, execution resumes and i is increased by 1.

Program 5 - Generate Even Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
2
4
6
8
10

Explanation

The Generator starts with 2.

After every yield, the value is increased by 2.

Therefore, only even numbers are generated.

Program 6 - Generate Odd Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
3
5
7
9

Program 7 - Generate Squares

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
4
9
16
25

Explanation

The Generator calculates the square of each number.

Instead of creating and storing a complete list of squares, each square is generated only when required.

Program 8 - Generate Countdown

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
5
4
3
2
1

Explanation

The Generator starts from the given number.

After producing each value, the number is decreased by 1.

The process continues until the value becomes 0.

Program 9 - Generator Using range()

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
2
3
4
5

Program 10 - Convert Generator Values to List

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30, 40]

Explanation

A Generator Object can be converted into a list using list().

However, converting a Generator into a list generates and stores all values in memory.

Therefore, the main memory-saving advantage of the Generator is reduced when all generated values are converted into a list.

Generator Objects Can Be Exhausted

A Generator Object produces each value only once.

After all values have been consumed, the same Generator Object cannot automatically start again.

To iterate again, a new Generator Object must normally be created by calling the Generator Function again.

Program 11 - Generator Exhaustion

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30]

[]

Explanation

The first list(result) consumes all values from the Generator Object.

After that, the Generator is exhausted.

Therefore, the second list(result) returns an empty list.

Creating a New Generator Object

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30]

[10, 20, 30]

Explanation

Each call to numbers() creates a new and independent Generator Object.

Therefore, both Generator Objects can produce the complete sequence separately.

Program 12 - Fibonacci Sequence Using Generator

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
0
1
1
2
3
5
8
13
21
34

Explanation

The Generator produces Fibonacci numbers one at a time.

The variables a and b store the current and next Fibonacci values.

After each yield, the Generator preserves these variable values.

When execution resumes, the next Fibonacci number is calculated.

This approach is useful because a complete list of Fibonacci numbers does not need to be created before processing begins.

How State is Preserved

Generator Feature Description
Local Variables Their values are preserved between yield statements.
Execution Position The position where the function paused is remembered.
Next Request Execution resumes from the previous position.
Completion The Generator becomes exhausted after the function finishes.

Practical Applications of Generator Functions

  • Generating large number sequences.
  • Reading large files line by line.
  • Processing database records.
  • Handling streaming data.
  • Generating Fibonacci sequences.
  • Creating custom iterators.
  • Processing API data in batches.
  • Working with large datasets.

Advantages of Working with Generators

  • Values are generated only when required.
  • Memory consumption is reduced.
  • The execution state is automatically preserved.
  • Large sequences can be processed efficiently.
  • Generators work directly with for loops.
  • Generator code can be simpler than creating custom iterator classes.

Quick Summary

Concept Description
Multiple yield A Generator Function can produce multiple values.
next() Retrieves one value at a time.
for Loop Automatically iterates through Generator values.
Parameters Generator Functions can accept parameters.
State Preservation Local variables and execution position are preserved.
Generator Exhaustion A Generator Object cannot produce values again after it is exhausted.
Lazy Evaluation Values are generated only when requested.

Important Notes

  • A Generator Function can contain multiple yield statements.
  • Each yield pauses execution and produces one value.
  • The next request resumes execution from the previous position.
  • Generator Functions can accept parameters.
  • A for loop automatically handles Generator iteration.
  • Local variables preserve their values between yield statements.
  • A Generator Object is exhausted after all its values are consumed.
  • To process the sequence again, create a new Generator Object.
  • Converting a Generator to a list stores all generated values in memory.
  • Generators are especially useful for large datasets and sequences.

Introduction to Generator Expressions

In the previous sections, we learned how to create Generator Functions using the yield keyword.

Python also provides a shorter and simpler way to create generators called a Generator Expression.

A Generator Expression creates a Generator Object without defining a complete Generator Function.

Generator Expressions are similar to List Comprehensions, but they use parentheses () instead of square brackets [].

Like Generator Functions, Generator Expressions generate values one at a time using lazy evaluation.

What is a Generator Expression?

A Generator Expression is a compact way to create a Generator Object using a single expression.

It does not generate and store all values immediately.

Instead, each value is generated only when it is requested.

This makes Generator Expressions useful when working with large sequences of data.

Syntax

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
No output captured.

Syntax Explanation

Part Description
expression The operation performed on each element.
item The variable representing each element of the iterable.
iterable The sequence or collection being processed.
() Parentheses are used to create a Generator Expression.

First Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
at 0x...>

Explanation

The expression creates a Generator Object.

The values from 1 to 5 are not immediately stored in memory as a complete collection.

Instead, they are generated one at a time when requested.

The exact memory address shown in the Generator Object may be different each time the program runs.

Using next() with Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
2
3
4
5

Explanation

Each call to next() retrieves one value from the Generator Expression.

The Generator remembers its current position.

The next call continues from where the previous call stopped.

After all values are consumed, another call to next() raises StopIteration.

Using Generator Expression with for Loop

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
2
3
4
5

Explanation

A Generator Expression can be directly used with a for loop.

The loop retrieves one value at a time.

It automatically stops when the Generator is exhausted.

Program 1 - Generate Squares

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
4
9
16
25

Explanation

The expression x ** 2 calculates the square of each number.

Each square is generated only when the for loop requests it.

Program 2 - Generate Cubes

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 8, 27, 64, 125]

Explanation

The Generator Expression produces the cube of each number.

The list() function consumes the Generator and stores all generated values in a list.

Generator Expression with Condition

A Generator Expression can include an if condition.

The condition determines which elements should be generated.

Program 3 - Generate Even Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[2, 4, 6, 8, 10]

Program 4 - Generate Odd Numbers

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 3, 5, 7, 9]

Program 5 - Generate Numbers Greater Than 20

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[25, 30, 35]

Generator Expression with String Data

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['RAHUL', 'AMIT', 'NEHA', 'POOJA']

Generator Expression with String Condition

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
['Python', 'JavaScript']

List Comprehension

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 4, 9, 16, 25]

Equivalent Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
at 0x...>

[1, 4, 9, 16, 25]

List Comprehension vs Generator Expression

List Comprehension Generator Expression
Uses square brackets []. Uses parentheses ().
Creates a List. Creates a Generator Object.
Generates all values immediately. Generates values only when requested.
Stores all values in memory. Produces values one at a time.
Suitable for smaller collections. Suitable for large sequences.
Values can be accessed repeatedly. Values are consumed during iteration.
Supports indexing. Does not support direct indexing.

Memory Efficiency

The main advantage of Generator Expressions is memory efficiency.

A List Comprehension creates all values and stores them in memory immediately.

A Generator Expression creates values only when they are requested.

For a small collection, the difference may not be noticeable.

However, when processing millions of values, Generator Expressions can significantly reduce memory usage.

Example - Large Sequence

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
0
1
4

Explanation

The Generator Expression represents one million square values.

However, all one million values are not created and stored at once.

Only the requested values are generated.

This is why Generator Expressions are useful for processing large sequences.

Generator Expression Can Be Exhausted

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 2, 3]

[]

Explanation

The first list(numbers) consumes all values from the Generator.

After that, the Generator Object is exhausted.

Therefore, the second conversion produces an empty list.

To generate the sequence again, a new Generator Expression must be created.

Using sum() with Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
15

Explanation

The Generator Expression produces numbers from 1 to 5 one at a time.

The sum() function consumes these generated values and calculates the total.

When a Generator Expression is passed as the only argument to a function, an additional pair of parentheses is not required.

Using max() with Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
25

Using min() with Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1

Generator Function vs Generator Expression

Generator Function Generator Expression
Defined using def. Created using expression syntax.
Uses the yield keyword. Does not explicitly use yield.
Can contain multiple statements. Contains a single expression.
Suitable for complex generator logic. Suitable for simple generator logic.
Returns a Generator Object. Creates a Generator Object.
Supports lazy evaluation. Supports lazy evaluation.

Advantages of Generator Expressions

  • Short and concise syntax.
  • Memory efficient.
  • Supports lazy evaluation.
  • Useful for processing large sequences.
  • Works directly with functions such as sum(), min(), and max().
  • Does not require defining a separate Generator Function for simple operations.

Limitations of Generator Expressions

  • Values are consumed only once.
  • Does not support direct indexing.
  • Not suitable for complex multi-statement logic.
  • A new Generator Expression must be created after the previous Generator is exhausted.
  • Converting the complete Generator into a list removes its main memory-saving advantage.

Real-World Applications

  • Processing large datasets.
  • Reading and transforming large data streams.
  • Performing calculations on large number sequences.
  • Data preprocessing.
  • Filtering large collections.
  • Creating memory-efficient data pipelines.
  • Working with large files and database records.

Quick Summary

Concept Description
Generator Expression A compact way to create a Generator Object.
Syntax (expression for item in iterable)
Brackets Uses parentheses ().
Evaluation Lazy Evaluation
Memory Usage Memory efficient.
Value Generation One value at a time.
Direct Indexing Not supported.
Main Use Processing large sequences efficiently.

Important Notes

  • A Generator Expression is a short way to create a Generator Object.
  • It uses parentheses () instead of square brackets [].
  • Values are generated only when requested.
  • Generator Expressions support lazy evaluation.
  • They are more memory efficient than List Comprehensions for large sequences.
  • Generator values can be retrieved using next() or a for loop.
  • A Generator Expression can include conditions.
  • A Generator Object becomes exhausted after all values are consumed.
  • Generator Expressions do not support direct indexing.
  • They are suitable for simple generator logic, while Generator Functions are better for complex logic.

Generator Functions - Comparison, Summary, and Quiz

In the previous sections, we learned about Generator Functions, the yield keyword, Generator Objects, the next() function, and Generator Expressions.

In this section, we will compare Generator Functions with Normal Functions, Lists, and Generator Expressions.

We will also review the advantages, limitations, real-world applications, and important concepts related to Generators.

Normal Function vs Generator Function

Feature Normal Function Generator Function
Main Keyword return yield
Execution Normally executes when called. Calling it creates a Generator Object; execution begins when iteration starts.
Function State Execution is not resumed after return. Execution state is preserved between yield statements.
Value Generation Returns a result directly. Produces values one at a time.
Function Completion return terminates the function. yield pauses the function temporarily.
Memory Usage May use more memory when returning large collections. Memory efficient for large sequences.
Lazy Evaluation Not automatically used. Yes
Return Object Depends on the returned value. Generator Object

Example - Normal Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[10, 20, 30]

Example - Generator Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
10
20
30

Explanation

The Normal Function creates and returns the complete list.

The Generator Function produces one value at a time.

For very large sequences, generating values one at a time can reduce memory consumption.

Generator vs List

Feature List Generator
Value Storage Stores all values in memory. Generates values when requested.
Evaluation Eager Evaluation Lazy Evaluation
Memory Usage Can be high for large collections. Usually lower for large sequences.
Indexing Supported Not supported directly
Repeated Iteration Can normally be iterated multiple times. A Generator Object is consumed during iteration.
Length len() is supported. len() is not directly supported.
Best For Small or reusable collections. Large or streamed sequences.

Example - List vs Generator

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 4, 9, 16, 25]

 at 0x...>

Explanation

The List Comprehension immediately creates and stores all square values.

The Generator Expression creates a Generator Object.

The Generator values are produced only when they are requested.

Generator Function vs Generator Expression

Feature Generator Function Generator Expression
Creation Created using def. Created using expression syntax.
Keyword Uses yield. Does not explicitly use yield.
Syntax Uses a complete function definition. Uses parentheses ().
Logic Supports complex multi-statement logic. Best for simple expressions.
Return Returns a Generator Object when called. Creates a Generator Object directly.
Lazy Evaluation Yes Yes
Memory Efficient Yes Yes
Best Use Complex generator logic. Simple and concise generator logic.

Example - Generator Function

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
4
9
16
25

Equivalent Generator Expression

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
1
4
9
16
25

Generator Function vs Generator Expression - When to Use

Situation Recommended Approach
Simple transformation Generator Expression
Simple filtering Generator Expression
Multiple statements Generator Function
Complex conditions Generator Function
Multiple yield points Generator Function
Short one-line generation logic Generator Expression

return vs yield

Feature return yield
Used In Normal Functions Generator Functions
Function Behaviour Terminates the function. Pauses the function.
State Preservation Function does not resume after returning. Execution state is preserved.
Next Execution A new function call starts execution again. The next iteration resumes from the previous position.
Main Purpose Return a result. Produce a sequence lazily.

Generator Object and Iterator

A Generator Object is a type of iterator.

It produces one value at a time and remembers its current execution state.

Generator values can be retrieved using:

  • next()
  • A for loop
  • Functions that consume iterables such as sum(), list(), tuple(), min(), and max()

Once all values have been consumed, the Generator Object becomes exhausted.

Generator Exhaustion

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
[1, 2, 3]

[]

Explanation

The first list(numbers) consumes all values from the Generator.

The Generator is now exhausted.

Therefore, the second list(numbers) returns an empty list.

To iterate through the sequence again, a new Generator Object must be created.

Lazy Evaluation

Lazy Evaluation means that a value is generated only when it is required.

Generators do not normally calculate and store the complete sequence in advance.

This behaviour is one of the main reasons Generators are useful when working with large datasets and sequences.

Example - Lazy Evaluation

🐍
main.py
Python 3 Runtime
Loading Editor...
Output Preview
Generating 1
1
Doing Other Work
Generating 2
2

Explanation

Only the requested values are generated.

The third value is not generated because the Generator is not asked for another value.

This demonstrates the lazy behaviour of Generator Functions.

Advantages of Generator Functions

  • Memory efficient for large sequences.
  • Values are generated only when required.
  • Supports lazy evaluation.
  • Preserves local variables and execution state.
  • Can represent very large sequences without storing every value at once.
  • Useful for streaming data.
  • Works naturally with for loops.
  • Can simplify the creation of custom iterators.

Limitations of Generator Functions

  • Generator Objects are consumed during iteration.
  • They do not support direct indexing.
  • Their length cannot normally be obtained directly using len().
  • Values that have already been consumed cannot be accessed again from the same Generator Object.
  • A new Generator Object must be created if the sequence needs to be processed again.
  • Generators may be less convenient when random access to elements is required.
  • Debugging complex Generator logic may be more difficult for beginners.

When Should You Use Generators?

Generators are especially useful when:

  • The dataset is very large.
  • You do not need all values at the same time.
  • Values can be processed one by one.
  • You are reading a large file.
  • You are processing streamed data.
  • You are generating a large sequence.
  • You want to reduce memory consumption.
  • You need to create a data-processing pipeline.

When Should You Use a List Instead?

A List may be more suitable when:

  • You need direct indexing.
  • You need to access the same values repeatedly.
  • You need to modify individual elements.
  • You need to know the collection length immediately.
  • The collection is small enough to store comfortably in memory.

Real-World Applications of Generators

  • Reading large files line by line.
  • Processing large datasets.
  • Handling database query results.
  • Processing API responses in batches.
  • Streaming data processing.
  • Log file processing.
  • Generating Fibonacci sequences.
  • Generating large mathematical sequences.
  • Creating data pipelines.
  • Data preprocessing.

Complete Generator Functions Summary

Concept Description
Generator Function A special function that produces values one at a time.
yield Produces a value and pauses function execution.
Generator Object An iterator returned by calling a Generator Function.
next() Retrieves the next generated value.
for Loop Automatically iterates over Generator values.
StopIteration Indicates that the Generator has no more values.
Lazy Evaluation Generates values only when they are requested.
State Preservation Local variables and execution position are preserved between yields.
Generator Expression A compact way to create a Generator Object.
Generator Expression Syntax (expression for item in iterable)
Generator Exhaustion A Generator Object cannot automatically restart after all values are consumed.
Main Advantage Memory-efficient processing of large sequences.

Generator Functions - Complete Flow

Step Description
1 Define a Generator Function using yield.
2 Call the function to create a Generator Object.
3 Request a value using next() or iteration.
4 The function executes until it reaches yield.
5 The value is produced and the function pauses.
6 The execution state is preserved.
7 The next request resumes execution.
8 The process continues until the function finishes.
9 The Generator becomes exhausted.

Important Interview Questions

  1. What is a Generator Function in Python?
  2. What is the purpose of the yield keyword?
  3. What is the difference between return and yield?
  4. What does a Generator Function return when called?
  5. What is a Generator Object?
  6. How does the next() function work with a Generator?
  7. What is StopIteration?
  8. What is Lazy Evaluation?
  9. How does a Generator preserve its execution state?
  10. What happens when a Generator Object is exhausted?
  11. What is a Generator Expression?
  12. What is the difference between a Generator Function and a Generator Expression?
  13. What is the difference between a List Comprehension and a Generator Expression?
  14. Why are Generators memory efficient?
  15. Can a Generator Object be reused after it is exhausted?
  16. Do Generators support direct indexing?
  17. When should you use a Generator instead of a List?
  18. What are some real-world applications of Generators?

Important Notes

  • Generator Functions use the yield keyword.
  • Calling a Generator Function creates a Generator Object.
  • The function body begins execution when the Generator is iterated.
  • yield produces a value and pauses execution.
  • The Generator preserves its local variables and execution position.
  • next() retrieves one value at a time.
  • A for loop automatically handles Generator iteration and StopIteration.
  • Generators use lazy evaluation.
  • Generator Objects are consumed during iteration.
  • An exhausted Generator Object does not automatically restart.
  • Generator Expressions provide a concise way to create Generator Objects.
  • Generator Expressions use parentheses ().
  • Generators do not support direct indexing.
  • Lists are more suitable when repeated access and indexing are required.
  • Generators are especially useful for large datasets, streams, files, and sequences.

🧠 Test Your Knowledge

219 Questions

Progress: 0 / 219
Keep Going!Python - Function Arguments