What you'll learn
As programs grow, cramming everything into one script becomes a tangled mess. Functions let you break code into small, named, reusable pieces — the single most important skill for writing programs that stay understandable.
By the end you'll be able to:
- Define and call functions with
def - Use default, positional, and keyword arguments
- Accept any number of arguments with
*argsand**kwargs - Return single or multiple values
- Understand variable scope and the LEGB rule
- Write quick anonymous functions with
lambda
Defining functions
A function is a named block of code that performs one task. You define it once with def and call it as often as you like. It can take parameters (inputs) and hand back a result with return:
def greet(name):
return f"Hi, {name}"def — the keyword that starts a function.
Name — a verb in snake_case describing what it does.
Parameters — the inputs it needs, in parentheses.
return — hands a value back (optional).
def greet(name):
return f"Hello, {name}!"
def square(n):
return n * n
print(greet("Sara"))
print(square(5))Tip
calculate_tax, is_valid_email, send_receipt. If you need "and" to describe it, split it.Arguments: default, positional & keyword
Parameters can have default values, making them optional. And when calling, you can pass arguments by position or by keyword (naming them) — keywords make calls self-documenting and order-independent:
def greet(name, greeting="Hello"): # greeting has a default value
return f"{greeting}, {name}!"
print(greet("Sara")) # Hello, Sara!
print(greet("Omar", "Welcome")) # Welcome, Omar!
print(greet(name="Aisha", greeting="Hi")) # keyword argumentsA classic gotcha
def f(items=[]) — that list is created once and shared across all calls, causing surprising bugs. Use def f(items=None) and create a fresh list inside instead.*args & **kwargs
Sometimes you don't know how many arguments there'll be. *args collects any extra positional arguments into a tuple, and **kwargs collects any extra keyword arguments into a dictionary:
def total(*numbers): # *args: any number of positional args
return sum(numbers)
def describe(**info): # **kwargs: any number of keyword args
for key, value in info.items():
print(f"{key}: {value}")
print(total(1, 2, 3, 4)) # 10
describe(name="Sara", age=25)Return values
return sends a value back to the caller (a function with no return gives back None). A lovely Python feature: you can return several values at once as a tuple, and unpack them into separate names:
def min_max(numbers):
return min(numbers), max(numbers) # returns a tuple
low, high = min_max([4, 8, 1, 9, 3]) # unpack it into two names
print(low, high)Scope & the LEGB rule
A variable created inside a function is local — it exists only there. When Python encounters a name, it searches scopes in a fixed order, remembered as LEGB:
Functions can freely read outer variables, but to reassign a global one you must declare global (or nonlocal for an enclosing function's variable):
count = 0 # a global variable
def increment():
global count # needed to reassign the global
count += 1
increment()
increment()
print(count) # 2Note
global. It keeps functions self-contained and easy to test.Lambda functions
A lambda is a tiny, anonymous, one-expression function. You'll rarely name one — their real power is being passed inline as an argument, most commonly as a key for sorting:
square = lambda x: x * x
print(square(5)) # 25
# lambdas shine as arguments — e.g. sorting by a key
words = ["banana", "kiwi", "apple"]
words.sort(key=lambda w: len(w))
print(words) # sorted by lengthTip
def function with a name — it's clearer.Recap & quick check
Key takeaways
- Define functions with def; they take parameters and return a value (or None).
- Parameters can have defaults; arguments can be passed by position or keyword.
- *args gathers extra positional args (a tuple); **kwargs gathers extra keyword args (a dict).
- Return multiple values as a tuple and unpack them; local variables live only inside the function.
- Python resolves names by LEGB (Local, Enclosing, Global, Built-in); use global to reassign a global.
Quick check
1. Which keyword defines a function in Python?
2. What does a function return if it has no return statement?
3. What does *args collect?
4. How can a function return two values at once?
5. In what order does Python look up a name (LEGB)?
Superb — you've completed Phase 1! You can store data, make decisions, repeat work, and package code into functions. Next you'll dive into Phase 2 — Data Structures, starting with lists.