Python Functions



1. What are Functions?

A function is a reusable block of code that performs a specific task. It improves modularity, readability, and code reusability.

Syntax of a Function:

def function_name(parameters):
    """Docstring (optional): Describes the function."""
    # Function body
    return result  # (optional)

Example:

def greet(name):
    """This function greets the user by name."""
    print(f"Hello, {name}!")

greet("Alice")  # Output: Hello, Alice!

2. Advantages of Functions

  1. Code Reusability: Write code once and reuse it multiple times.
  2. Modularity: Divides complex code into smaller, manageable parts.
  3. Improves Readability: Functions make the code easier to understand.
  4. Avoids Repetition: Reduces duplication of code.
  5. Easy Debugging: Isolated blocks of code help debug efficiently.

3. Types of Functions in Python

a) Built-in Functions

Python comes with many built-in functions like:

  • print(): Prints output to the console.
  • len(): Returns the length of an object.
  • type(): Returns the type of an object.
  • max() and min(): Find maximum and minimum.
  • sum(): Returns the sum of elements.
  • sorted(): Returns a sorted version of an iterable.

Example:

nums = [10, 20, 30]
print(len(nums))  # 3
print(max(nums))  # 30
print(sum(nums))  # 60

b) User-Defined Functions

Functions that are defined by the user.

Example:

def add(a, b):
    return a + b

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

c) Anonymous Functions (Lambda Functions)

  • Anonymous functions are defined using the lambda keyword.
  • Syntax: lambda arguments: expression
  • They are single-line functions without a name.

Example:

square = lambda x: x * x
print(square(4))  # Output: 16

add = lambda x, y: x + y
print(add(3, 5))  # Output: 8

4. Pass by Value vs. Pass by Reference

Pass by Value:

  • A copy of the actual value is passed to the function.
  • Changes made inside the function do not affect the original variable.
  • Immutable types (e.g., int, float, str, tuple) behave like pass by value.

Example:

def modify(x):
    x = 10  # Local modification
    print("Inside function:", x)

num = 5
modify(num)
print("Outside function:", num)  # Original value remains unchanged

Output:

Inside function: 10
Outside function: 5

Pass by Reference:

  • A reference to the actual object is passed to the function.
  • Changes made inside the function affect the original variable.
  • Mutable types (e.g., list, dict, set) behave like pass by reference.

Example:

def modify(lst):
    lst.append(4)  # Modify the original list
    print("Inside function:", lst)

nums = [1, 2, 3]
modify(nums)
print("Outside function:", nums)  # Original list is modified

Output:

Inside function: [1, 2, 3, 4]
Outside function: [1, 2, 3, 4]

5. Recursion

Recursion occurs when a function calls itself. It is useful for solving problems like factorial, Fibonacci series, and tree traversal.

Example: Factorial using Recursion

def factorial(n):
    if n == 0:  # Base case
        return 1
    return n * factorial(n - 1)  # Recursive call

print(factorial(5))  # Output: 120

Key Points about Recursion:

  1. Every recursive function must have a base case to terminate.
  2. Excessive recursion can lead to a stack overflow (e.g., infinite recursion).
  3. Recursive functions are often slower than iterative solutions.

6. Scope and Lifetime of Variables

Scope:

Defines where a variable can be accessed:

  1. Local Scope: Variables declared inside a function.
  2. Global Scope: Variables declared outside all functions.
  3. Enclosing Scope: Variables in nested functions.
  4. Built-in Scope: Built-in names like print() or len().

Example:

x = 10  # Global variable

def func():
    y = 5  # Local variable
    print("Inside function:", y)

func()
print("Outside function:", x)

Output:

Inside function: 5
Outside function: 10

Lifetime:

  • The lifetime of a variable refers to how long the variable exists in memory.
  • Local variables exist only as long as the function runs.
  • Global variables persist throughout the program.

7. Example Combining Concepts

# Global variable
counter = 0

def recursive_sum(n):
    """Recursively calculates the sum of numbers from 1 to n."""
    global counter  # Accessing the global variable
    counter += 1    # Track recursive calls
    if n == 0:      # Base case
        return 0
    return n + recursive_sum(n - 1)

result = recursive_sum(5)
print("Sum:", result)           # Output: 15
print("Function calls:", counter)  # Output: 6

Key Takeaways:

  1. Functions allow modularity and reusability.
  2. Built-in functions provide common functionalities.
  3. User-defined functions are customized by the programmer.
  4. Lambda functions are anonymous, single-line functions.
  5. Pass by value applies to immutable types; pass by reference applies to mutable types.
  6. Recursion solves problems by breaking them into smaller instances.
  7. Scope determines where a variable can be accessed.

Let me know if you need more examples or clarification! 😊

Comments

Popular posts from this blog

Keyword , Identifier, Indentation, Comments & Documentation

DSA Lab 8 program

DSA Lab 7 Program