Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
8 views

Exploring Functions in Python

This document provides an overview of Python functions, highlighting their importance in code reusability, modularity, and scalability. It covers various aspects such as defining functions, parameters, arguments, and advanced concepts like lambda functions and decorators. Additionally, it explains the differences between global and local variables, as well as the use of *args and **kwargs for handling variable numbers of arguments.

Uploaded by

sujitmaity2000
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Exploring Functions in Python

This document provides an overview of Python functions, highlighting their importance in code reusability, modularity, and scalability. It covers various aspects such as defining functions, parameters, arguments, and advanced concepts like lambda functions and decorators. Additionally, it explains the differences between global and local variables, as well as the use of *args and **kwargs for handling variable numbers of arguments.

Uploaded by

sujitmaity2000
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

1/13/25, 2:52 PM 06-Functions

Python Functions: Basics and


Applications
Introduction
In Python, a function is a reusable block of code designed to perform a specific task.
Functions help make programs modular, readable, and efficient by breaking complex
problems into smaller, manageable pieces.

Why Functions?
Code Reusability: Write once, use multiple times, reducing redundancy.
Modularity: Break programs into smaller parts, making them easier to understand
and debug.
Scalability: Functions allow for scaling programs by adding functionality without
altering existing code.
Built-in and Customizable: Python provides many built-in functions, and
developers can create custom functions to suit their needs.

This notebook showcases my practice and understanding of Python functions, including:

1. Basics of defining and calling functions.


2. Understanding parameters, arguments, and return values.
3. Advanced concepts like lambda functions, decorators, and recursive functions.

Join me in exploring Python functions and their role in building efficient, modular, and
scalable programs!

Let's create a function(with docstring)


In [1]: # Create a function with (docs string)

def is_even(num):
"""
This function returns if a given number is even or odd
input- any valid integer
output- odd/even
created on - 12 January 2025
"""
if type(num) == int:
if num % 2 == 0:
return 'even'
else:
return 'odd'
else:
return 'kuchh v karte ho bhai '

file:///C:/Users/goura/Downloads/06-Functions.html 1/18
1/13/25, 2:52 PM 06-Functions

What is the lifetime of a function in


Python?
The lifetime of a function in Python is limited to its execution. It becomes active when
called and remains so until it returns a value or completes execution. Outside this period,
the function does not exist in an active state.

In [2]: # Function
# Function_name(input)

for i in range(1,11):
x = is_even(i)
print(i,x)

1 odd
2 even
3 odd
4 even
5 odd
6 even
7 odd
8 even
9 odd
10 even

2 Point of views
In [3]: is_even('hello')

Out[3]: 'kuchh v karte ho bhai '

In [4]: is_even(9)

Out[4]: 'odd'

Parameters Vs Arguments
at the time of making function that is known as parameter and at the time when we
are using that function that is known as argument

Tpes of Arguments
Default Argument
Positional Argument
Keyword Argument

Default Argument

file:///C:/Users/goura/Downloads/06-Functions.html 2/18
1/13/25, 2:52 PM 06-Functions

Using Default Arguments, you can assign a default value to a function parameter.
This makes the function more flexible and helps in handling errors.

If the user does not pass any value, the default value is used, allowing the function to
work without interruption.

Example:
def greet(name="Guest"):
print(f"Hello, {name}! Welcome to Python programming.")

# Calling the function without passing an argument


greet()
# Output: Hello, Guest! Welcome to Python programming.

# Calling the function with an argument


greet("Gourab")
# Output: Hello, Gourab! Welcome to Python programming.

In [5]: def calculate_total(price, tax=0.05):


return price + (price * tax)

print(calculate_total(100))

print(calculate_total(100, 0.10))

105.0
110.0

Positional Argument
Positional Argument ka matlab hai ki function ke arguments ko unke position ke basis
par pass kiya jata hai.
Arguments ko unhi order mein pass karna hota hai, jisme function ke parameters define
kiye gaye hain.

Agar arguments galat order mein diye gaye, to unexpected behavior ya error aa sakti hai.
Positional arguments simple aur basic tarika hai function ke parameters ko value assign
karne ka.

Example:
def introduce(name, age):
print(f"My name is {name} and I am {age} years old.")

# Correct positional arguments


introduce("Gourab", 25)
# Output: My name is Gourab and I am 25 years old.

# Incorrect positional arguments


introduce(25, "Gourab")
# Output: My name is 25 and I am Gourab years old.

file:///C:/Users/goura/Downloads/06-Functions.html 3/18
1/13/25, 2:52 PM 06-Functions

In [6]: def calculate_area(length, width):


return length * width

# Correct positional arguments


print(calculate_area(5, 3))
# Output: 15

# Incorrect positional arguments


print(calculate_area(3, 5))
# Output: 15 (though the result is correct, the interpretation of the dimensions

15
15

Keyword Argument
Keyword Arguments are arguments passed to a function by explicitly specifying the
parameter name along with its value.
This makes the function call more readable and allows arguments to be passed in any
order.

Example:
def introduce(name, age, city):
print(f"My name is {name}, I am {age} years old, and I live in
{city}.")

# Using keyword arguments


introduce(name="Gourab", age=25, city="Kolkata")
# Output: My name is Gourab, I am 25 years old, and I live in Kolkata.

# Changing the order of keyword arguments


introduce(city="Kolkata", age=25, name="Gourab")
# Output: My name is Gourab, I am 25 years old, and I live in Kolkata.

In [7]: def calculate_total(price, tax=0.05, discount=0.0):


total = price + (price * tax) - discount
return total

In [8]: # Using keyword arguments


print(calculate_total(price=100, tax=0.1, discount=5))
# Output: 105.0

105.0

In [9]: # Skipping optional arguments using default values


print(calculate_total(price=100))
# Output: 105.0

105.0

*args and **kwargs

file:///C:/Users/goura/Downloads/06-Functions.html 4/18
1/13/25, 2:52 PM 06-Functions

*args and **kwargs are special Python keywords that allow functions to accept a
variable number of arguments.
They are used when the number of arguments that will be passed to the function is
unknown.

*args
*args allows a function to accept any number of positional arguments.
These arguments are passed as a tuple to the fuut: Sum of numbers: 0

In [10]: ### Example:

def add_numbers(*args):
total = sum(args)
print(f"Sum of numbers: {total}")

In [11]: # Passing multiple positional arguments


add_numbers(1, 2, 3, 4, 5)

Sum of numbers: 15

In [12]: # Passing no arguments


add_numbers()

Sum of numbers: 0

**kwargs
**kwargs allows a function to accept any number of keyword arguments.
These arguments are passed as a dictionary to the function.

In [13]: def introduce(**kwargs):


for key, value in kwargs.items():
print(f"{key}: {value}")

In [14]: # Passing multiple keyword arguments


introduce(name="Gourab", age=25, city="Kolkata")

name: Gourab
age: 25
city: Kolkata

In [15]: # Passing no arguments


introduce()

In [16]: def display_info(*args, **kwargs):


print("Positional arguments:", args)
print("Keyword arguments:", kwargs)

# Passing both positional and keyword arguments


display_info(1, 2, 3, name="Gourab", age=25)

file:///C:/Users/goura/Downloads/06-Functions.html 5/18
1/13/25, 2:52 PM 06-Functions

Positional arguments: (1, 2, 3)


Keyword arguments: {'name': 'Gourab', 'age': 25}

In [17]: print(is_even.__doc__)

This function returns if a given number is even or odd


input- any valid integer
output- odd/even
created on - 12 January 2025

In [18]: # to get the documents of any function


print(print.__doc__)

Prints the values to a stream, or to sys.stdout by default.

sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.

In [19]: def display(**kwargs):


for (key,value) in kwargs.items():
print(key,'-->',value)

In [20]: display(Bihar='Patna',Punjab='chandigarh',Telangana='Hyderabad')

Bihar --> Patna


Punjab --> chandigarh
Telangana --> Hyderabad

Points to remember while using *args and **kwargs

order of the arguments matter(normal -> *args -> **kwargs )


The words “args” and “kwargs” are only a convention, you can use any name of your
choice

Variables in Python: Global and Local


Global Variable
A global variable is a variable that is defined in the main program scope and is
accessible throughout the program, including within functions (unless shadowed by
a local variable with the same name).

Local Variable
A local variable is a variable that is defined inside a function and is only accessible
within that function's scope.

file:///C:/Users/goura/Downloads/06-Functions.html 6/18
1/13/25, 2:52 PM 06-Functions

Key Difference:
1. Local variables cannot be accessed outside their function.
2. Global variables, however, can be accessed and modified (if required) inside a
function using the global keyword.

Example:
In [21]: # Global variable
x = 10

def my_function():
# Local variable
y = 5
print(f"Local variable y: {y}")
print(f"Global variable x accessed inside function: {x}")

my_function()

Local variable y: 5
Global variable x accessed inside function: 10

In [22]: # Accessing global variable outside the function


print(f"Global variable x outside function: {x}")

Global variable x outside function: 10

In [23]: # Accessing local variable outside function will throw an error


print(y) # this line will result in a NameError

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[23], line 2
1 # Accessing local variable outside function will throw an error
----> 2 print(y)

NameError: name 'y' is not defined

In [24]: # If a variable is not defined inside the function, it can use the global variab
# However, changes to the global variable are not allowed.

def h(y):
x += 1

x = 5
h(x)
print(x)

file:///C:/Users/goura/Downloads/06-Functions.html 7/18
1/13/25, 2:52 PM 06-Functions

---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
Cell In[24], line 8
5 x += 1
7 x = 5
----> 8 h(x)
9 print(x)

Cell In[24], line 5, in h(y)


4 def h(y):
----> 5 x += 1

UnboundLocalError: cannot access local variable 'x' where it is not associated wi


th a value

In [25]: # Variable Scope in Python

def g(x):
# Local scope: x is a local variable within the function
print(x) # This will print the value of x passed to the function
print(x + 1) # This will print the value of x + 1

x = 5 # Global variable
a = g(x) # Calling the function with x as an argument
print(a) # This will print the value of a, which is None since g() does

5
6
None

In [26]: # Variable Scope and Function Behavior

def f(y):
# Local variable x is created inside the function with a value of 1
x = 1
x += 1 # Local x is incremented by 1, so x becomes 2
print(x) # This will print the local x, which is 2

x = 5 # Global variable x is set to 5


f(x) # Calling the function f() with x as the argument
print(x) # This will print the global x, which is still 5 (unchanged by th

2
5

In [27]: def h(y):


x += 1 # This will throw an error because x is not declared as global

x = 5 # Global variable x
h(x) # Calling the function h() with x as the argument
print(x) # This will not execute due to the error in the function

file:///C:/Users/goura/Downloads/06-Functions.html 8/18
1/13/25, 2:52 PM 06-Functions

---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
Cell In[27], line 5
2 x += 1 # This will throw an error because x is not declared as globa
l
4 x = 5 # Global variable x
----> 5 h(x) # Calling the function h() with x as the argument
6 print(x)

Cell In[27], line 2, in h(y)


1 def h(y):
----> 2 x += 1

UnboundLocalError: cannot access local variable 'x' where it is not associated wi


th a value

In [28]: def f(x):


x = x+1
print("in f(x): x =",x)
return x

x = 3
z = f(x)
print("in main program scope: z = ",z)
print("in main program scope: x = ",x)

in f(x): x = 4
in main program scope: z = 4
in main program scope: x = 3

Nested Functions
In Python, a nested function is a function defined inside another function.
A nested function can access variables from its enclosing function's scope. These are
often used for cases where you want to use a function temporarily or to create closures.

Example:
In [29]: # Nested Functions in Python

def f():
def g():
print('inside function g')
# f() # Uncommenting this would lead to a RecursionError

g() # Calling the inner function g()


print('inside function f')

# Calling the outer function f()


f()

inside function g
inside function f

In [30]: def outer_function(x):


# This is the outer function
def inner_function(y):

file:///C:/Users/goura/Downloads/06-Functions.html 9/18
1/13/25, 2:52 PM 06-Functions

# This is the nested (inner) function


return y + 1

result = inner_function(x) # Calling the inner function


return result

x = 5
print(outer_function(x)) # Output: 6

In [31]: # Nested Functions with Variable Scope

def g(x):
def h(x):
x = 'abc' # This assigns 'abc' to the local variable x within function
x += 1 # This modifies the local variable x in function g
print("in g(x): x =", x) # This prints the value of x after it is increment
h(x) # Calling the nested function h() with x
return x # Returning the value of x after incrementing

x = 3 # Global variable x
z = g(x) # Calling function g with x as argument
print(z) # This prints the returned value of x from function g

in g(x): x = 4
4

In [32]: def g(x):


def h(x):
x = x+1
print('in h(x): x = ',x)
x += 1
print('in g(x): x = ',x)
h(x)
return(x)

x = 3
z = g(x)
print('in main programme scope: x= ', x)
print('in main programme scope: z= ', z)

in g(x): x = 4
in h(x): x = 5
in main programme scope: x= 3
in main programme scope: z= 4

In [33]: # Functions as First-Class Citizens in Python

def square(num):
# A simple function that returns the square of the given number
return num**2

# type() and id() functions


print(type(square)) # This prints the type of the 'square' function
print(id(square)) # This prints the unique identifier (memory address) of the

<class 'function'>
2166862109472

In [34]: # Reassigning a Function to a Variable

file:///C:/Users/goura/Downloads/06-Functions.html 10/18
1/13/25, 2:52 PM 06-Functions

def square(num):
return num**2

# Reassigning the function 'square' to the variable 'x'


x = square

# Checking the unique identifier (memory address) of 'x' (which now refers to th
print(id(x))

# Calling the function using 'x' (it behaves the same as 'square')
print(x(3)) # This will print 9, as 3^2 = 9

2166862113472
9

In [35]: # deleting a function


# del square

In [36]: # storing
L = [1,2,3,4,5,square]
L

Out[36]: [1, 2, 3, 4, 5, <function __main__.square(num)>]

Functions and Immutability in Python


Functions are Immutable: Functions in Python are immutable in the sense that
their identity (memory address) cannot be changed once they are defined. However,
you can reassign a function to a different variable or name, as shown in the previous
example.

Sets and Immutability: A set in Python is an unordered collection that only allows
immutable data types as elements. This means that you cannot add mutable data
types like lists, dictionaries, or other sets into a set.

Why Functions are Allowed in Sets


Functions are immutable objects in Python, so they can be added to a set because they
have a stable hash value and identity. Python allows adding functions to sets, just like
other immutable types (e.g., integers, strings, tuples).

Example:
In [37]: # Adding a function to a set
def square(num):
return num**2

my_set = {square}

# Checking if the function is in the set


print(square in my_set) # Output: True

True

file:///C:/Users/goura/Downloads/06-Functions.html 11/18
1/13/25, 2:52 PM 06-Functions

In [38]: def cube(num):


return num**3

my_set.add(cube)

# Checking if cube is added to the set


print(cube in my_set) # Output: True

True

In [39]: # Functions as Arguments in Python

def func_a():
# Function that prints a message
print('inside func_a')

def func_b(z):
# Function that takes another function as argument
print('inside func_b')
return z() # Calls the function passed as argument (z)

# Passing func_a as an argument to func_b


print(func_b(func_a))

inside func_b
inside func_a
None

Benefits of Using a Function


Code Modularity
Functions allow you to divide your code into smaller, manageable modules. For example,
you can create separate functions for tasks like login, registration, and searching. If
there's an issue with the login functionality, you can focus on debugging only that
specific code block, without affecting the others.

Code Readability
Since the code is divided into separate functions, it becomes easier to read and
understand. In a team environment, you can assign different functionalities to different
team members. For instance, one person can work on the login function, another on
registration, etc. This enhances collaboration and reduces complexity.

Code Reusability
Once a function is written, it can be reused multiple times across your program. This
reduces redundancy and makes your code more efficient. For example, if you need to use
the login function at several points in your application, you can call it each time without
having to rewrite the same code.

file:///C:/Users/goura/Downloads/06-Functions.html 12/18
1/13/25, 2:52 PM 06-Functions

Lambda Function: A, B: A + B
Lambda Keyword:
The lambda keyword is used to create an anonymous function (a function without
a name) in Python.

Parameters (A, B) :
A lambda function can take one or more parameters, which should be separated by
commas.
Unlike regular functions, lambda functions do not require parentheses around the
parameters if there are no default values.

Colon : :
The colon : separates the parameters from the expression. It signals the start of
the function body.

Expression (A + B) :
The expression is a single, valid Python expression that gets evaluated and returned.
In a lambda function, you cannot include statements or multiple expressions. In this
case, A + B is the expression that returns the sum of A and B .

Lambda Function
A lambda function is a small anonymous function defined using the lambda
keyword.

Anonymous Function: A function that does not have a name.


Syntax: lambda arguments: expression

Key Points:
A lambda function can take any number of arguments, but it can only have one
expression.
The expression is evaluated and returned when the function is called.
Lambda functions are often used for short-term, quick operations where defining a
full function is unnecessary.

file:///C:/Users/goura/Downloads/06-Functions.html 13/18
1/13/25, 2:52 PM 06-Functions

In [40]: # Lambda function that adds two numbers


add = lambda A, B: A + B

# Calling the lambda function


print(add(5, 3)) # Output: 8

Difference Between Lambda vs Normal Function


Lambda Function:
No Name: Lambda functions are anonymous, meaning they don't have a name.
No Explicit Return: Lambda functions don't use the return keyword. The
expression in the lambda is automatically returned.
One Line: Lambda functions are written in a single line, making them concise.
Not Reusable: Lambda functions are typically used for short-term tasks and are not
intended for reuse like normal functions.

Normal Function:
Has a Name: Normal functions are defined using the def keyword and can be
called by their name.
Return Value: Normal functions explicitly use the return keyword to return a
value.
Multiple Lines: Normal functions can span multiple lines, allowing more complex
logic.
Reusable: Normal functions are reusable and can be called multiple times
throughout your code.

Example:
In [41]: # Lambda Function Example
add = lambda x, y: x + y
print(add(3, 4)) # Output: 7

file:///C:/Users/goura/Downloads/06-Functions.html 14/18
1/13/25, 2:52 PM 06-Functions

In [42]: # Normal Function Example


def add_function(x, y):
return x + y
print(add_function(3, 4)) # Output: 7

In [43]: a = lambda s: 'a' in s


a("hello")

Out[43]: False

In [44]: a = lambda x:'even' if x%2 == 0 else "odd"


a(9)

Out[44]: 'odd'

Higher-Order Function (HOF)


A Higher-Order Function (HOF) is a function that either:

1. Returns a function as its output (a function that returns another function).


2. Receives a function as an argument (a function that takes another function as
input).

Explanation:
Higher-order functions allow us to treat functions as first-class citizens by passing
them as arguments or returning them from other functions.
These functions are commonly used in functional programming and are essential for
creating more modular and reusable code.

Higher order function ek aisa function hota hai jiske return me aapko khud ek
fuction milta hai (ek aisa fuction jo ek fuction ko return karta hai) ya phir aisa fuction
jo input me dusre fuction ko recieve kare usko higher order function kahte hain.

In [45]: # Example

def square(x):
return x**2

# HOF

def transform (f,L):


output = []
for i in L:
output.append(f(i))

print(output)

L = [1,2,3,4,5]
# transform(square,L)

file:///C:/Users/goura/Downloads/06-Functions.html 15/18
1/13/25, 2:52 PM 06-Functions

# OR
transform(lambda x:x**2,L)

[1, 4, 9, 16, 25]

map()
map always expects two things: a lambda function and an iterable (like a list). Using
map , you can apply any logic or perform mapping on the elements of an iterable.

For example, if you're given a list and asked to find the square of each element, you can
easily do this using map() .

Example:
In [46]: # square the item of list
list(map(lambda x:x**2,[2,4,6,8,10,12]))

Out[46]: [4, 16, 36, 64, 100, 144]

In [47]: # Square of each number in the list using map


numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)

[1, 4, 9, 16, 25]

In [48]: # odd even labelling of list item

l = [1,2,3,4,5,6,7,8,9]
list(map(lambda x:'even' if x%2 ==0 else 'odd',l))

Out[48]: ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

In [49]: users = [{
'name':'gourab',
'age':26,
'gender':'male'},
{
'name':'saurabh',
'age':24,
'gender':'male'
},
{
'name':'suman',
'age':26,
'gender':'male'
},
{
'name':'saroj',
'age':26,
'gender':'male'
}
]

# for finding the name of users

file:///C:/Users/goura/Downloads/06-Functions.html 16/18
1/13/25, 2:52 PM 06-Functions

list(map(lambda users:users['name'],users ))

Out[49]: ['gourab', 'saurabh', 'suman', 'saroj']

In [50]: # for finding the age of users

list(map(lambda users:users['age'],users ))

Out[50]: [26, 24, 26, 26]

In [51]: # for finding the gender of users

list(map(lambda users:users['gender'],users ))

Out[51]: ['male', 'male', 'male', 'male']

What does map() do?


map() creates a new list from a given list based on some logic, and the logic comes
from a lambda function.

Higher-Order Function: map() is a higher-order function, which means it requires


another function (in this case, a lambda function) as its input.
The lambda function defines the operation to be applied to each element in the
given iterable (such as a list).

filter()
filter() is also a higher-order function that filters a given list based on a condition. It
requires two things:

1. A lambda function that defines the filtering condition.


2. A list to apply the condition on.

Difference between map() and filter() :


map() applies a logic to each item in the list.
filter() only keeps the values that meet the condition (i.e., where the lambda
function returns True ) and filters out the rest.

Example 1: Filtering numbers greater than 5


In [52]: l = [1, 3, 5, 7, 9, 11]
result = list(filter(lambda x: x > 5, l))
print(result)

[7, 9, 11]

file:///C:/Users/goura/Downloads/06-Functions.html 17/18
1/13/25, 2:52 PM 06-Functions

In [53]: fruits = ['Apple', 'guava', 'cherry', 'Acerola Cherries', 'African Breadfruit',


'Akebi Fruit', 'Alpine Strawberry', 'African Mango', 'Amanatsu oranges
result = list(filter(lambda x: x.startswith('A'), fruits))
print(result)

['Apple', 'Acerola Cherries', 'African Breadfruit', 'Akebi Fruit', 'Alpine Strawb


erry', 'African Mango', 'Amanatsu oranges']

reduce()
Imagine you have a list, and you want to calculate the sum of all its items. You can do this
in a single line using reduce() . Like map() and filter() , reduce() also requires
two things:

1. A lambda function that defines the operation.


2. A list of items on which to perform the operation.

Example: Sum of all items in a list


In [54]: import functools

# Sum of all items in the list


result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result)

15

working--> (1+2+3+4+5)(1+2,3,4,5)(3+3,4,5)(6+4,5)(10+5)

It picks only two items at a time, compares them, and discards the one that is false.
Then, it picks the next item, because one of them is already being carried over. It
works iteratively, but at any point, it only operates on two items. Finally, it will return
a single value.

In [55]: functools.reduce(lambda x,y:x if x<y else y, [23,11,45,10,1])

Out[55]: 1

In [56]: functools.reduce(lambda x,y:x if x>y else y, [23,11,45,10,1])

Out[56]: 45

In [ ]:

file:///C:/Users/goura/Downloads/06-Functions.html 18/18

You might also like