Functions in Python

Functions are reusable blocks of code that perform specific tasks. They help in organizing your code, making it more modular, readable, and easier to debug. Python allows you to define your own functions using the def keyword, and you can call these functions whenever needed.

Defining a Function:

Python
def greet(name):
    return "Hello, " + name

# Calling a function
message = greet("Alice")
print(message)  # Output: Hello, Alice

Arguments and Parameters:

Functions can take arguments, which are the values you pass to the function when calling it. Parameters are the variables in the function definition that hold these values:

Python
def add_numbers(a, b):
    return a + b

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

Default Parameters:

You can specify default values for parameters, which will be used if no argument is provided:

Python
def greet(name, greeting="Hello"):
    return greeting + ", " + name

print(greet("Alice"))  # Output: Hello, Alice
print(greet("Bob", "Hi"))  # Output: Hi, Bob

Keyword Arguments:

Python allows you to call functions using keyword arguments, where you explicitly specify the parameter names:

Python
def describe_pet(pet_name, animal_type="dog"):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")

describe_pet(pet_name="Willie")  # Output: I have a dog. My dog's name is Willie.
describe_pet(animal_type="cat", pet_name="Whiskers")  # Output: I have a cat. My cat's name is Whiskers.

Variable-Length Arguments:

You can define functions that accept an arbitrary number of arguments using *args for positional arguments and **kwargs for keyword arguments:

Python
def make_pizza(size, *toppings):
    print(f"\nMaking a {size}-inch pizza with the following toppings:")
    for topping in toppings:
        print(f"- {topping}")

make_pizza(12, "pepperoni")
make_pizza(16, "mushrooms", "green peppers", "extra cheese")

Lambda Functions:

Lambda functions are small anonymous functions defined using the lambda keyword. They are often used for short, throwaway functions:

Python
# A lambda function to square a number
square = lambda x: x * x

print(square(5))  # Output: 25

Function Annotations:

Function annotations provide a way to attach metadata to function parameters and return values, often used for type hinting:

Python
def add_numbers(a: int, b: int) -> int:
    return a + b

result = add_numbers(10, 15)
print(result)  # Output: 25

Higher-Order Functions:

Higher-order functions are functions that accept other functions as arguments or return functions as their result:

Python
def apply_operation(operation, x, y):
    return operation(x, y)

def multiply(a, b):
    return a * b

result = apply_operation(multiply, 3, 4)
print(result)  # Output: 12

Return Values:

Functions can return a value using the return statement. If no return statement is used, the function returns None by default:

Python
def multiply(a, b):
    return a * b

result = multiply(4, 5)
print(result)  # Output: 20

Understanding and utilizing functions effectively is essential in Python for structuring your code, making it reusable, and improving readability. Whether you"re working with simple or complex programs, mastering functions is key to writing efficient and maintainable Python code.