1. Defining and Calling Functions
A function is a named block of code that performs a specific task. You define it once, then call it whenever you need that task done.Function Syntax
Every function follows this pattern:def: keyword that creates a function.- Function name followed by parentheses
(). - Colon
:to start the function body. - Indented code block (the function body).
Naming Functions
Follow these rules for function names (Snake Case):- Use lowercase letters.
- Separate words with underscores.
- Be descriptive about what the function does.
2. Parameters & Arguments
Parameters let you pass data into functions. Instead of hardcoding values, you make functions flexible to work with different inputs.[!NOTE] The variables in the function definition are parameters. The actual values you pass when calling the function are arguments.
Positional Arguments
By default, Python matches the arguments you pass to the parameters in the definition by their position (order).Default Values
You can give parameters default values to make them optional:[!TIP] Always put parameters with default values at the end of the parameter list.
Keyword Arguments
You can call functions using parameter names for clarity, which allows you to pass them in any order:3. Return Values
Use thereturn statement to send a value back from a function to the caller.
[!IMPORTANT] When Python encounters areturnstatement, it immediately exits the function. Any code after thereturnstatement will not execute.
Returning Multiple Values
You can return multiple values from a function by separating them with commas. Python wraps them in a tuple automatically:4. Flexible & Enforced Arguments
Python provides advanced options for handling dynamic numbers of arguments and enforcing calling styles.Variable-Length Arguments (*args)
Prefix a parameter name with a single asterisk * to accept any number of positional arguments. Inside the function, args is a tuple.
Variable Keyword Arguments (**kwargs)
Prefix a parameter name with a double asterisk ** to accept any number of keyword arguments. Inside the function, kwargs is a dictionary.
Argument Ordering Rules
When mixing argument types, you must define them in this exact order:- Standard positional arguments
*args- Keyword-only arguments
**kwargs
Positional-Only (/) and Keyword-Only (*) Parameters
- Positional-Only (
/): Parameters before/must be passed positionally. - Keyword-Only (
*): Parameters after*must be passed as keyword arguments.
Recursion
Recursion is a programming technique where a function calls itself directly or indirectly to solve a problem. It works by breaking down a complex problem into smaller, more manageable sub-problems of the same type. Every recursive function must have two main components:- Base Case: The stopping condition that returns a value directly without making further recursive calls. Without a base case, the function will call itself infinitely, leading to a stack overflow.
- Recursive Step: The part of the function where it calls itself with a modified argument, moving the inputs closer to the base case.
Example 1: Factorial of a Number
The factorial of (written as ) is the product of all positive integers less than or equal to . Mathematical definition:- (Base case)
- (Recursive step)
Example 2: Fibonacci Numbers
The Fibonacci sequence is a series of numbers where each number is the sum of the two preceding ones, usually starting with 0 and 1. Mathematical definition:- , (Base cases)
- (Recursive step)
Python Recursion Limit
To prevent stack overflow and out-of-memory crashes due to infinite loops, Python enforces a maximum recursion depth (typically set to 1000). You can check and modify this limit using thesys module:
5. Variable Scope & LEGB Rule
The scope of a variable refers to the region of a program where that variable is accessible.LEGB Lookup Order
When you reference a variable name, Python searches for it in this strict order:- Local: Inside the current function.
- Enclosing: Inside any enclosing (outer) functions.
- Global: Top-level variables defined in the module/file.
- Built-in: Python’s pre-loaded functions (like
len,print).
NameError.
The global and nonlocal Keywords
global: Declares that a variable inside a function refers to the global scope, allowing you to modify it.nonlocal: Declares that a variable inside a nested function refers to the enclosing (outer) scope, allowing you to modify it.
Functions as First-Class Objects
Functions can be:- Assigned to variables.
- Passed as arguments.
- Returned from functions.
- Accessed using attributes like
__name__.
Lambda Functions
A lambda is a small anonymous function consisting of a single expression.map(), filter(), and sorted().
Variable-Length Arguments (*args and **kwargs)
*argscollects extra positional arguments into a tuple.**kwargscollects extra keyword arguments into a dictionary.
Closures
A closure is a nested function that remembers variables from its enclosing scope.Decorators
A decorator extends the behavior of a function without modifying its source code.Decorators with Arguments
Use*args and **kwargs to support functions with any number of arguments.
- Declarative Programming
- Higher-Order Functions
Generators
A generator is a special type of function that produces values one at a time instead of returning them all at once. It uses theyield keyword instead of return. Generators are memory-efficient because they generate values only when needed.
Advantages
- Uses less memory for large datasets.
- Produces values lazily (on demand).
- Suitable for processing streams of data or large files.
Creating a Generator
Using next()
A generator can be iterated manually using the next() function.
Generator Expression
Similar to list comprehensions, Python supports generator expressions.Generator vs List
Declarative Programming
Declarative programming focuses on what you want to achieve, while imperative programming focuses on how to achieve it.Imperative vs Declarative
Imperative (How):Higher-Order Functions
A Higher-Order Function is a function that:- Accepts one or more functions as arguments.
- Returns a function as its result.
Passing Functions as Arguments
Returning Functions
Real-World Example
Built-in Higher-Order Functions
map()
Applies a function to every element of an iterable.
filter()
Returns only the elements that satisfy a condition.
reduce()
The reduce() function (from the functools module) combines all elements into a single value.
Functional Pipeline Example
The following example combinesfilter(), map(), and reduce() to compute the sum of squares of even numbers.
Pythonic Alternative
Althoughmap(), filter(), and reduce() are useful, Python often provides a simpler and more readable solution using comprehensions and built-in functions.
Practice & Exercises
To reinforce what you’ve learned in this section (defining functions, scopes, lambda expressions, closures, decorators, and functional programming), practice with these interactive notebooks:Follow-Along Practice
Practice function definitions, positional/keyword arguments, variable scope rules, closures, wrapper decorators, and higher-order functions (map, filter, reduce).💻 VS Code | 🚀 Colab | 📥 Download
Practice Exercises
Test your knowledge with hands-on exercises including positional/keyword argument formatters, nonlocal scope counters, closure factories, execution timer decorators, and functional pipelines.💻 VS Code | 🚀 Colab | 📥 Download