1. Introduction to Functions
A function is a named block of code that performs a specific task. Functions help break a large program into smaller, manageable modules.
Advantages of using functions:
- Code Reusability: Write once, use multiple times.
- Modularity: Divide a complex program into smaller parts.
- Readability: Well-named functions make code self-documenting.
- Debugging: Isolate and test individual functions easily.
- Maintainability: Changes in one function do not affect others.
2. Types of Functions
| Type | Description | Example |
|---|---|---|
| Built-in Functions | Predefined functions available in Python | print(), len(), type(), input() |
| Module Functions | Functions imported from modules | math.sqrt(), random.randint() |
| User-defined Functions | Functions created by the programmer | def calculate_area(): |
3. Defining a Function
Functions are defined using the def keyword followed by the function name and parentheses.
def function_name(parameters):
"""Docstring (optional)"""
# Function body
return value Rules for naming functions:
- Must start with a letter or underscore.
- Can contain letters, digits, and underscores.
- Cannot use Python reserved keywords.
- Function names are case-sensitive.
Example:
def greet():
print("Hello, welcome to Python programming!")
4. Calling a Function
A function must be called to execute its code. The function call uses the function name followed by parentheses.
# Function definition
def greet():
print("Hello, world!")
# Function call
greet()
# Output: Hello, world! A function must be defined before it is called. Python executes code sequentially from top to bottom.
5. Parameters and Arguments
Parameters are variables listed in the function definition. Arguments are the actual values passed to the function when calling it.
def add(a, b): # a and b are parameters
return a + b
result = add(5, 3) # 5 and 3 are arguments
print(result) # Output: 8 Types of Arguments
| Argument Type | Description | Example |
|---|---|---|
| Positional | Arguments matched by position | add(5, 3) |
| Keyword | Arguments matched by parameter name | add(a=5, b=3) |
| Default | Parameters with default values | def add(a, b=0): |
| Variable-length | Accepts any number of arguments | def add(*args): |
6. Default Parameters
Default parameters allow a function to be called with fewer arguments than defined. The default value is used when an argument is not provided.
def power(base, exp=2):
return base ** exp
print(power(4)) # Output: 16 (4 squared)
print(power(4, 3)) # Output: 64 (4 cubed) Rules:
- Default parameters must come after non-default parameters.
def func(a, b=5, c=10):is valid.def func(a=5, b):is invalid and raises SyntaxError.
7. Keyword Arguments
Keyword arguments allow passing arguments by parameter name, making the function call more readable and order-independent.
def student_info(name, age, grade):
print(f"Name: {name}, Age: {age}, Grade: {grade}")
student_info(age=16, name="Riya", grade="A")
# Output: Name: Riya, Age: 16, Grade: A Positional arguments must come before keyword arguments in function calls. func(5, b=3) is valid; func(a=5, 3) is not.
8. Variable-Length Arguments
Python allows functions to accept a variable number of arguments using *args (positional) and **kwargs (keyword).
*args (Arbitrary Positional Arguments)
def sum_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # Output: 6
print(sum_all(10, 20, 30, 40)) # Output: 100 **kwargs (Arbitrary Keyword Arguments)
def display_info(**details):
for key, value in details.items():
print(f"{key}: {value}")
display_info(name="Amit", city="Delhi", subject="CS")
# Output:
# name: Amit
# city: Delhi
# subject: CS 9. Return Statement
The return statement exits a function and sends a value back to the caller. A function can return multiple values as a tuple.
def calculator(a, b):
add = a + b
sub = a - b
mul = a * b
div = a / b
return add, sub, mul, div
result = calculator(10, 3)
print(result) # Output: (13, 7, 30, 3.333...) Important points about return:
- A function without a return statement returns
None. - Multiple values are returned as a tuple.
- Return stops function execution immediately.
- Any code after a return statement inside the function is unreachable.
10. Scope of Variables
Scope refers to the region of a program where a variable is accessible. Python has three levels of scope:
| Scope | Description | Visibility |
|---|---|---|
| Local | Variables defined inside a function | Only within that function |
| Global | Variables defined at the top level of a script | Accessible throughout the program |
| Built-in | Predefined names in Python | Accessible everywhere |
Python follows the LEGB (Local, Enclosing, Global, Built-in) rule for name resolution.
11. Global and Local Variables
x = 10 # Global variable
def my_func():
x = 5 # Local variable (different from global x)
print("Local x:", x) # Output: Local x: 5
my_func()
print("Global x:", x) # Output: Global x: 10 Local variables cannot be accessed outside the function. Global variables can be read inside functions but cannot be modified without the global keyword.
12. The global Keyword
To modify a global variable inside a function, use the global keyword.
counter = 0
def increment():
global counter
counter += 1
increment()
increment()
print(counter) # Output: 2 Without the global keyword, Python would create a new local variable named counter instead of modifying the global one.
13. Mutable and Immutable Arguments
Python treats mutable and immutable objects differently when passed as arguments.
| Type | Examples | Behaviour |
|---|---|---|
| Immutable | int, float, str, tuple | Changes create a new object; original remains unchanged |
| Mutable | list, dict, set | Changes affect the original object |
def modify_list(lst):
lst.append(4) # Modifies the original list
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # Output: [1, 2, 3, 4] 14. Recursion
Recursion is a technique where a function calls itself to solve a smaller instance of the same problem. Every recursive function must have a base case to stop recursion.
def factorial(n):
if n == 0 or n == 1: # Base case
return 1
else:
return n * factorial(n - 1) # Recursive call
print(factorial(5)) # Output: 120 Advantages: Clean and elegant code for problems like tree traversal, factorial, Fibonacci series.
Disadvantages: Higher memory usage due to function call stack; risk of stack overflow for deep recursion.
15. Lambda Functions
A lambda function is a small anonymous function defined using the lambda keyword. It can take any number of arguments but returns only one expression.
# Syntax: lambda arguments: expression
square = lambda x: x ** 2
print(square(5)) # Output: 25
# Using with filter()
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # Output: [2, 4, 6]
# Using with map()
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # Output: [2, 4, 6, 8, 10, 12] 16. Docstrings
A docstring (documentation string) is a string literal that appears as the first statement in a function, module, class, or method definition. It describes what the function does.
def calculate_area(radius):
"""Calculate the area of a circle given its radius."""
pi = 3.14159
return pi * radius * radius
print(calculate_area.__doc__)
# Output: Calculate the area of a circle given its radius. Docstrings are accessed using the __doc__ attribute and are also used by the help() function.
17. Best Practices for Writing Functions
- Use descriptive function names (verbs or verb-noun combinations).
- Keep functions small and focused on a single task.
- Include docstrings to document function behaviour.
- Avoid using global variables inside functions when possible.
- Use default parameters carefully to avoid unexpected behaviour.
- Return early when an error condition is detected.
- Test each function independently.
- Follow a consistent naming convention (snake_case for functions).
18. Revision Questions and Answers
Very Short Answer Questions
1. What is a function?
A function is a named block of code that performs a specific task.
2. Which keyword is used to define a function in Python?
The def keyword.
3. What is the difference between a parameter and an argument?
A parameter is a variable in the function definition, while an argument is the actual value passed during a function call.
4. What does a function return if no return statement is used?
It returns None.
5. What is a lambda function?
A lambda function is a small anonymous function defined using the lambda keyword.
Short Answer Questions
1. Differentiate between local and global variables.
Local variables are defined inside a function and accessible only within that function. Global variables are defined at the top level and accessible throughout the program. To modify a global variable inside a function, the global keyword must be used.
2. Explain default parameters with an example.
Default parameters have a default value assigned in the function definition. If the caller does not provide a value, the default is used. Example: def power(base, exp=2): return base ** exp. Calling power(4) returns 16, and power(4, 3) returns 64.
3. What are *args and **kwargs?*args allows a function to accept any number of positional arguments as a tuple. **kwargs allows a function to accept any number of keyword arguments as a dictionary.
Long Answer Questions
1. Explain variable scope in Python with examples.
Python has Local, Enclosing, Global, and Built-in scopes (LEGB rule). A variable defined inside a function has local scope. A variable defined at the module level has global scope. When a variable is referenced, Python searches in LEGB order. Inside a function, reading a global variable is allowed, but modifying it requires the global keyword. Example: x = 10; def f(): x = 5 creates a local x inside f, leaving the global x unchanged.
2. Write a recursive function to calculate the nth Fibonacci number and explain its working.def fib(n): if n <= 1: return n; return fib(n-1) + fib(n-2). The base case returns n when n is 0 or 1. For larger values, the function calls itself with n-1 and n-2, adding their results. The recursive calls continue until they reach the base case, then the results propagate back up.