Functions

Defining and calling functions

What Are Functions?

A function is a block of reusable code that performs a specific task. You define functions to avoid repeating code, enhance readability, and make your code more modular.

1. Defining a Function

To define a function, you use the def keyword followed by the function name, parentheses, and a colon (:). The indented code that follows is the body of the function, where the logic happens.

Syntax:

def function_name(parameters):
# function body
# code to be executed

Example 1: A Simple Function

def greet():
print(“Hello, welcome!”)

  • def defines the function.
  • greet() is the function name.
  • The body contains the print() statement.

This function doesn’t accept any parameters and simply prints a message when called.

2. Calling a Function

After defining a function, you can call it by using its name followed by parentheses.

Syntax:

function_name()

Example 2: Calling the greet() function

greet()

Output:

Hello, welcome!

The function greet() is executed when called, and it prints the message.

3. Functions with Parameters

Functions can accept parameters — values that are passed into the function when it’s called.

Syntax:

def function_name(parameter1, parameter2):
# code

Example 3: Function with Parameters

def greet(name):
print(f”Hello, {name}!”)

Calling the Function with an Argument

greet(“Alice”)

Output:

Hello, Alice!

The function greet() accepts a name parameter and prints a personalized greeting.

4. Functions with Return Values

Functions can return a value using the return keyword, allowing you to send results back to where the function was called.

Syntax:

def function_name():
return value

Example 4: Function with a Return Value

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

Calling the Function and Using the Return Value

result = add(5, 3)
print(result)

Output:

8

The add() function returns the sum of a and b, and the result is stored in the result variable, which is then printed.

5. Functions with Multiple Parameters and Default Values

Functions can also have default parameters, meaning that if no value is passed for them, a default value will be used.

Syntax:

def function_name(param1, param2=default_value):
# code

Example 5: Function with a Default Parameter

def greet(name, greeting=”Hello”):
print(f”{greeting}, {name}!”)

Calling the Function with and without Default Parameter

greet(“Bob”) # Uses default greeting
greet(“Alice”, “Good morning”) # Custom greeting

Output:

Hello, Bob!
Good morning, Alice!

Summary of Key Points:

  • Defining a function: Use def followed by the function name and parameters.
  • Calling a function: Simply write the function name followed by parentheses.
  • Parameters: Functions can accept inputs (parameters) to customize their behavior.
  • Return values: Use return to send results from a function back to the caller.
  • Default values: Parameters can have default values in case no argument is provided.

Example of Multiple Concepts:

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

result1 = multiply(5) # Uses default value for b
result2 = multiply(5, 3) # Custom value for b

print(result1) # Output: 10
print(result2) # Output: 15

Parameters, arguments, and return values

1. Parameters

Parameters are variables that are defined in a function’s signature (the function definition). They act as placeholders for values that are passed into the function when it is called.

Parameters let you write generic, reusable functions that can handle different inputs.

Syntax for Parameters:

def function_name(parameter1, parameter2):
# function body

Example: Parameters in Action

def greet(name, greeting=”Hello”):
print(f”{greeting}, {name}!”)

  • name and greeting are parameters.
  • greeting has a default value (“Hello”), so it’s optional when calling the function.

Key Points:

  • Parameters define the inputs a function requires.
  • Parameters are used within the function body.

2. Arguments

Arguments are the actual values that you pass into a function when you call it. The function receives arguments and uses them to perform its tasks.

Arguments are provided in the function call and match the function’s parameters in order.

Syntax for Arguments:

function_name(argument1, argument2)

Example: Passing Arguments

greet(“Alice”, “Good morning”)

  • “Alice” and “Good morning” are arguments.
  • “Alice” is passed to the name parameter, and “Good morning” is passed to the greeting parameter.

Key Points:

  • Arguments are the real values passed to the function when it is called.
  • Arguments replace parameters with actual data.

3. Return Values

A return value is the result that a function sends back after it completes its task. A function can return any kind of value — numbers, strings, lists, etc.

The return keyword is used to send a value back from a function. Once return is executed, the function exits, and the returned value can be used or stored outside of the function.

Syntax for Return Values:

def function_name():
return value

Example: Function with Return Value

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

  • The add() function returns the sum of a and b.
  • When the function finishes, it sends the result back to the caller.

Key Points:

  • A function can return a value using return.
  • The function stops executing after a return statement.

Example of Using Parameters, Arguments, and Return Value Together:

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

# Calling the function with arguments:
result1 = multiply(5) # Uses default b=1
result2 = multiply(5, 3) # Custom b=3

print(result1) # Output: 5 (5 * 1)
print(result2) # Output: 15 (5 * 3)

  • Parameters: a and b are defined in the function signature.
  • Arguments: 5 and 3 are passed when calling the function.
  • Return Value: The result of a * b is returned and stored in result1 and result2.

Key Takeaways:

  • Parameters: Variables defined in the function to receive inputs.
  • Arguments: Values passed to the function when calling it (matching parameters).
  • Return Values: The result that the function sends back after completing its task, allowing you to use the output outside the function.

Variable scope

What is Variable Scope?

Variable scope refers to the region of a program where a variable can be accessed. In Python, the scope is influenced by where the variable is declared and where it is used.

Types of Scope in Python

  • Local Scope
  • Enclosing Scope
  • Global Scope
  • Built-in Scope

1. Local Scope

A variable has local scope if it is defined inside a function or a block of code. This means it is only accessible within that function or block.

  • Local variables are created when the function is called and destroyed when the function finishes execution.

Example of Local Scope:

def my_function():
x = 10 # x is local to my_function
print(x)

my_function() # Output: 10
# print(x) # This would cause an error because x is local to my_function

In the example, x is local to my_function(), and trying to access x outside the function will raise a NameError.

2. Enclosing Scope (Nonlocal)

Enclosing scope refers to the scope of a function within another function. Variables defined in the outer (enclosing) function are accessible to the inner (nested) function.

  • These variables are not local to the inner function but can be modified using the nonlocal keyword.

Example of Enclosing Scope:

def outer_function():
x = 20 # x is in the enclosing scope
def inner_function():
print(x) # Can access x from the enclosing function
inner_function()

outer_function() # Output: 20

Here, inner_function() can access x from the outer_function() because x is in an enclosing scope.

3. Global Scope

A variable has global scope if it is defined at the top level of the script or module (outside any function). Global variables can be accessed from any part of the program, including inside functions (but not always modified directly without the global keyword).

  • Global variables exist throughout the life of the program.

Example of Global Scope:

x = 50 # x is a global variable

def my_function():
print(x) # Can access global x inside the function

my_function() # Output: 50
print(x) # Output: 50

In this example, x is defined in the global scope and can be accessed inside the function my_function().

Modifying a Global Variable:

To modify a global variable inside a function, use the global keyword:

x = 50 # Global variable

def my_function():
global x
x = 100 # Modifies the global x

my_function()
print(x) # Output: 100

Without the global keyword, trying to assign to x inside the function would create a local variable x instead of modifying the global one.

4. Built-in Scope

Built-in scope refers to the names that are available in Python’s built-in namespace, which includes functions like print(), len(), sum(), and more. These names are available throughout the entire program.

  • Built-in variables and functions are part of Python’s core language and are always accessible.

Example of Built-in Scope:

print(len(“Hello”)) # ‘len’ is a built-in function

In this example, print() and len() are built-in functions, available globally without needing to be imported or defined.

LEGB Rule (Local, Enclosing, Global, Built-in)

When you reference a variable, Python follows the LEGB rule to look for it:

  • Local: First, Python looks for the variable in the local function scope.
  • Enclosing: If it’s not found, Python checks in any enclosing functions (from outer to inner).
  • Global: If it’s not found in enclosing scopes, Python searches for the variable in the global scope.
  • Built-in: If the variable is still not found, Python checks the built-in scope for the variable.

Example of LEGB Rule:

x = 5 # Global variable

def outer_function():
x = 10 # Enclosing variable
def inner_function():
x = 15 # Local variable
print(x) # Prints the local x, not global or enclosing
inner_function()

outer_function() # Output: 15
print(x) # Output: 5 (global x remains unaffected)

Here, inside inner_function(), Python uses the local x because it’s closest. The enclosing and global x are not used.

Modifying Variables in Different Scopes

  • Local variable: Can be modified directly within the function.
  • Enclosing variable: Can be modified using the nonlocal keyword.
  • Global variable: Can be modified using the global keyword.

Key Takeaways:

  • Local scope: Variables are accessible only inside the function where they are defined.
  • Enclosing scope: Variables are accessible in nested functions.
  • Global scope: Variables are accessible throughout the program.
  • Built-in scope: Python’s core functions and variables.
  • The LEGB rule determines where Python looks for a variable

Lambda functions

What Is a Lambda Function?

A lambda function is a small, anonymous function defined using the lambda keyword instead of def. It is used to create throwaway functions — typically for short, simple operations — without naming them.

Syntax of a Lambda Function:

lambda arguments: expression

  • lambda: Keyword that defines the function.
  • arguments: Input parameters (can be zero or more).
  • expression: A single expression to evaluate and return.

Note: The body of a lambda must be a single expression, not multiple lines or statements.

Example 1: Basic Lambda

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

This defines a lambda that returns the square of x. It behaves like:

def square(x):
return x * x

Example 2: Lambda with Multiple Arguments

add = lambda a, b: a + b
print(add(3, 5)) # Output: 8

Example 3: Lambda with No Parameters

greet = lambda: “Hello!”
print(greet()) # Output: Hello!

Lambda vs Regular Functions:

Feature def Function Lambda Function
Name Yes (named function) No (anonymous unless assigned to variable)
Multi-line support Yes (multiple statements) No (single expression only)
Use cases Reusable, complex logic One-time, short operations
Return Explicit return statement Implicit return of expression result
Best for Functions called multiple times Simple operations passed as arguments

Where Are Lambda Functions Commonly Used?

Lambda functions are often used with other functions that accept functions as arguments (like map(), filter(), sorted(), etc.).

Example 4: Using lambda with map()

nums = [1, 2, 3, 4]
squares = list(map(lambda x: x**2, nums))
print(squares) # Output: [1, 4, 9, 16]

Example 5: Using lambda with filter()

nums = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # Output: [2, 4]

Example 6: Sorting with Lambda

people = [(“Alice”, 30), (“Bob”, 25), (“Eve”, 35)]
sorted_people = sorted(people, key=lambda person: person[1])
print(sorted_people) # Sorted by age
# Output: [(‘Bob’, 25), (‘Alice’, 30), (‘Eve’, 35)]

When to Use Lambda Functions

Use a lambda when:

  • You need a small, quick function.
  • It’s used only once or in a limited scope.
  • You’re passing it as an argument to a higher-order function.

Avoid lambda when:

  • The function is complex or involves multiple steps.
  • You need to reuse or debug it.

Summary:

  • Lambda functions are anonymous, one-line functions.
  • Use lambda args: expression.
  • Great for quick tasks, especially with map(), filter(), sorted(), etc.
  • They simplify short, functional-style code but should not replace full def functions for more complex logic.

Want to explore lambda with custom sorting, combining with list comprehensions, or higher-order functions like reduce()? Just say the word!

Leave a Comment