Python - Functions

9.
How do you use the *args and **kwargs syntax in function definitions?

In Python, the *args and **kwargs syntax in function definitions allow you to accept a variable number of arguments. *args is used for variable positional arguments, while **kwargs is used for variable keyword arguments.

Let's illustrate this with an example:

def example_function(arg1, *args, kwarg1="default_value", **kwargs):
    print("arg1:", arg1)
    print("Additional positional arguments (*args):", args)
    print("Keyword argument (kwarg1):", kwarg1)
    print("Additional keyword arguments (**kwargs):", kwargs)

# Call the function with different arguments
example_function("value1", "value2", "value3", kwarg1="custom_value", key1="custom_key", key2="another_key")

In this example, the example_function takes arg1 as a regular argument, *args to collect additional positional arguments, kwarg1 as a keyword argument with a default value, and **kwargs to collect additional keyword arguments. The function then prints these values.

Output:

arg1: value1
Additional positional arguments (*args): ('value2', 'value3')
Keyword argument (kwarg1): custom_value
Additional keyword arguments (**kwargs): {'key1': 'custom_key', 'key2': 'another_key'}

10.
Explain the concept of scope in Python functions.

The concept of scope in Python refers to the region or context in which a variable is defined and can be accessed. There are two main types of scope:

1. Local Scope:

  • Variables defined within a function have a local scope.
  • They are only accessible within that specific function.
  • Once the function execution completes, the local variables are destroyed.
  • Local variables can have the same names as variables in other functions or in the global scope without causing conflicts.

2. Global Scope:

  • Variables defined outside of any function or at the module level have a global scope.
  • They can be accessed and modified from any part of the code, including within functions.
  • Global variables persist throughout the program's execution.

Let's illustrate the concept of scope with an example:

# Global variable
global_variable = "I am a global variable"

def example_function():
    # Local variable
    local_variable = "I am a local variable"
    print(local_variable)

    # Accessing the global variable from within the function
    print(global_variable)

# Call the function
example_function()

# Trying to access the local variable outside the function will result in an error
# Uncommenting the line below will raise an error
# print(local_variable)

Output:

I am a local variable
I am a global variable

11.
What is a lambda function, and how is it different from a regular function?

A lambda function in Python is an anonymous function created using the lambda keyword. Unlike regular functions defined using the def keyword, lambda functions are concise and can have only one expression. They are often used for short-term operations where a full function definition would be overly verbose.

The syntax for a lambda function is:

lambda arguments: expression

Here's a comparison between a regular function and a lambda function:

# Regular function
def add(x, y):
    return x + y

# Lambda function
add_lambda = lambda x, y: x + y

# Calling both functions
result_regular = add(3, 5)
result_lambda = add_lambda(3, 5)

print(f"Result (Regular Function): {result_regular}")
print(f"Result (Lambda Function): {result_lambda}")

Output:

Result (Regular Function): 8
Result (Lambda Function): 8

In this example, both the regular function and the lambda function perform the same addition operation. The lambda function, however, is more concise and is often used for simple operations where a named function is not required.


12.
How do you call a function recursively in Python?

In Python, a function can call itself, and this is known as recursion. Recursive functions are useful for solving problems that can be broken down into smaller subproblems of the same type. The base case is crucial to prevent infinite recursion and provide a termination condition.

Here's an example of a recursive function to calculate the factorial of a number:

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

# Calling the recursive function
result = factorial(5)

print(f"The factorial of 5 is: {result}")

Output:

The factorial of 5 is: 120

In this example, the factorial function calls itself recursively until it reaches the base case (n == 0 or n == 1), at which point the recursion stops, and the final result is calculated.