Functions: Reusable Blocks of Code
A function is a named block of code that performs a specific task. You define a function once and can then "call" (run) it whenever you need it. This follows the DRY (Don't Repeat Yourself) principle of programming.
Functions are defined using the def keyword. They can take inputs, called parameters (or arguments), and can optionally return a value using the return keyword.
Python
# A simple function definition
def greet(name):
    """This function greets the person passed in as a parameter."""
    message = f"Hello, {name}!"
    return message
# Calling the function and storing the returned value
greeting = greet("Bob")
print(greeting) # Output: Hello, Bob!
Parameters vs. Arguments
- Parameter: The variable listed inside the parentheses in the function definition (e.g., name in def greet(name):).
- Argument: The actual value that is sent to the function when it is called (e.g., "Bob" in greet("Bob")).
Lambda Functions: Anonymous and On-the-Fly
A lambda function is a small, anonymous function defined with the lambda keyword. It can take any number of arguments but can only have one expression. They are useful when you need a simple function for a short period, often as an argument to a higher-order function (like map or sorted).
Syntax: lambda arguments: expression
Python
# A regular function to add 5 to a number
def add_five(x):
    return x + 5
# The equivalent lambda function
add_five_lambda = lambda x: x + 5
print(add_five(10))        # Output: 15
print(add_five_lambda(10)) # Output: 15
# Common use case: sorting a list of tuples by the second element
points = [(1, 5), (4, 2), (9, 8)]
points_sorted = sorted(points, key=lambda p: p[1])
print(points_sorted) # Output: [(4, 2), (1, 5), (9, 8)]
Understanding Scope (LEGB Rule)
Scope defines the visibility of a variable. Not all variables are accessible from all parts of the program. Python resolves variable names using the LEGB rule, searching in this order:
- L - Local: Variables defined inside the current function.
- E - Enclosing: Variables in the local scope of enclosing functions (e.g., in nested functions).
- G - Global: Variables defined at the top level of a module or declared global with the global keyword.
- B - Built-in: Names pre-assigned in Python (e.g., print, len, str).
Python
x = "global" # Global scope
def outer_function():
    x = "enclosing" # Enclosing scope for inner_function
    def inner_function():
        x = "local" # Local scope
        print(f"Inside inner_function, x is: {x}")
    inner_function()
    print(f"Inside outer_function, x is: {x}")
outer_function()
print(f"In the global scope, x is: {x}")
# Output:
# Inside inner_function, x is: local
# Inside outer_function, x is: enclosing
# In the global scope, x is: global
The global and nonlocal keywords can be used to modify variables in outer scopes, but they should be used with caution.