Atlas

Roadmap

Functions & Scope

Functions

Mar 21, 2026

In This Chapter

  • How to define functions with parameters, defaults, and return values
  • How *args and **kwargs work for flexible signatures
  • Why Python functions are first-class objects
  • When lambda helps and when it hurts readability
  • A classic interview pitfall: mutable default arguments

Defining Functions

Use def to define a function:

def greet(name: str) -> str:
    return f"Hello, {name}!"

greet("Alan")
python

Type hints are optional, but they make the function contract easier to read.

Parameters and Defaults

Functions can take zero or more parameters:

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

add(3, 5)   # 8
python

Default parameters provide fallback values:

def greet(name: str, greeting: str = "Hello") -> str:
    return f"{greeting}, {name}!"

greet("Alan")
greet("Alan", "Hey")
python

Parameters with defaults must come after required parameters.

Python also supports keyword-only parameters:

def connect(host: str, *, timeout: int = 5, retries: int = 2) -> None:
    ...

connect("db.local", timeout=10, retries=3)
python

Return Values

If a function does not explicitly return a value, Python returns None:

def say_hi():
    print("hi")

result = say_hi()
print(result)  # None
python

Python can also return multiple values by packing them into a tuple:

def min_max(nums: list[int]) -> tuple[int, int]:
    return min(nums), max(nums)
python

*args and **kwargs

*args collects extra positional arguments into a tuple:

def total(*args: int) -> int:
    return sum(args)
python

**kwargs collects extra keyword arguments into a dictionary:

def display(**kwargs) -> None:
    for key, value in kwargs.items():
        print(f"{key}: {value}")
python

You can combine them with normal parameters:

def log(event: str, *args, level: str = "INFO", **kwargs) -> None:
    ...
python

Functions Are First-Class Objects

In Python, functions are values. You can assign them to variables, pass them to other functions, and return them from functions.

def shout(text: str) -> str:
    return text.upper()

formatter = shout
formatter("hello")   # "HELLO"
python

This is why callbacks, decorators, and higher-order functions work naturally in Python.

Lambda Functions

Lambda is a compact syntax for a tiny anonymous function:

square = lambda x: x ** 2

names = ["Charlie", "Alan", "Bob"]
names.sort(key=lambda name: len(name))
python

Use lambda for short local logic. Once the function needs multiple steps or better naming, switch to def.

Mutable Default Arguments

One of Python's most common interview traps looks like this:

def add_item(item, bucket=[]):
    bucket.append(item)
    return bucket

add_item("a")   # ["a"]
add_item("b")   # ["a", "b"]
python

The list is created once when the function is defined, not once per call.

The safer pattern is:

def add_item(item, bucket=None):
    if bucket is None:
        bucket = []
    bucket.append(item)
    return bucket
python

Detailed name lookup rules, global, nonlocal, and LEGB belong in the next article.

Key Questions

Q: What is the difference between *args and **kwargs?

*args captures extra positional arguments as a tuple. **kwargs captures extra keyword arguments as a dictionary.

Q: What does it mean that Python functions are first-class objects?

It means functions behave like values: they can be stored in variables, passed into other functions, and returned from them.

Q: What is the difference between a parameter and an argument?

A parameter is the variable name in the function definition. An argument is the concrete value passed at call time.

Q: What is the mutable default argument pitfall?

Default values are evaluated once when the function is defined. If the default is mutable, multiple calls can share the same object. Use None as the default and create the mutable object inside the function.

Q: What does a function return if there is no return statement?

It returns None.

Q: What is the difference between lambda and def?

Lambda is a single-expression anonymous function. def gives you a named function with full statements and better readability.