Defining and calling a function
A function is a named, reusable block of code. Define it with def, call it with parentheses:
def greet(name):
"""Return a greeting for name.""" # docstring
return f"Hello, {name}!"
message = greet("Ada")
print(message)
print(greet("Linus"))
print(greet.__doc__)The value after return is sent back to the caller. A function with no return (or a bare return) gives back None. Functions must be defined before they are called.
Parameters, defaults and keyword arguments
def power(base, exponent=2):
return base ** exponent
print(power(3)) # uses default exponent
print(power(3, 3))
print(power(exponent=4, base=2)) # keyword args, any order
def describe(name, *, age): # everything after * must be keyword
return f"{name} is {age}"
print(describe("Ada", age=36))Parameters with defaults must come after those without. Never use a mutable default such as items=[] — the same list is shared across every call. Use items=None and create the list inside.
Returning multiple values
def min_max(values):
return min(values), max(values) # returns a tuple
low, high = min_max([4, 9, 1, 7])
print(low, high)
def divide(a, b):
if b == 0:
return None # early return on bad input
return a / b
print(divide(10, 4), divide(1, 0))*args and **kwargs
Accept any number of positional arguments with *args (a tuple) and any keyword arguments with **kwargs (a dict):
def total(*numbers):
return sum(numbers)
print(total(1, 2, 3), total())
def tag(name, **attrs):
parts = " ".join(f'{k}="{v}"' for k, v in attrs.items())
return f"<{name} {parts}>"
print(tag("a", href="/", target="_blank"))
# unpacking the other way
nums = [3, 5, 7]
print(total(*nums))
opts = {"href": "/x"}
print(tag("a", **opts))Scope: local vs global
counter = 0 # global
def bump():
local = 1 # exists only inside bump
global counter
counter += local
bump(); bump()
print(counter)
def outer():
x = "outer"
def inner():
nonlocal x
x = "changed by inner"
inner()
return x
print(outer())A function can read global variables freely, but to assign one you must declare global. In practice, prefer passing values in and returning results — functions that rely on globals are hard to test.
Lambda functions
A lambda is a one-expression anonymous function, mostly used as a key or callback:
square = lambda n: n * n
print(square(6))
people = [("Ada", 36), ("Linus", 54), ("Grace", 85)]
print(sorted(people, key=lambda p: p[1]))
print(list(map(lambda p: p[0].upper(), people)))
print(list(filter(lambda p: p[1] > 40, people)))If a lambda needs a name, or more than one expression, write a normal def instead.
Recursion
A function may call itself. Every recursive function needs a base case that stops the recursion:
def factorial(n):
if n <= 1: # base case
return 1
return n * factorial(n - 1)
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
print(factorial(5), fib(10))
print([fib(i) for i in range(10)])Python's default recursion limit is 1,000 levels. Deep recursion is usually better rewritten as a loop. The naive fib above is exponentially slow; the standard library lesson shows how functools.lru_cache fixes it in one line.
Type hints and docstrings
def area(width: float, height: float) -> float:
"""Return the area of a rectangle.
Args:
width: horizontal size in metres.
height: vertical size in metres.
"""
return width * height
print(area(2.5, 4))
help(area)Hints are ignored at runtime but make code self-documenting and let editors catch mistakes. Next lesson: modelling things with classes and objects.
Frequently asked questions
What is the difference between a parameter and an argument?
A parameter is the name in the function definition (def f(x)); an argument is the value you pass when calling (f(5)). People use the words interchangeably in conversation.
What does return do in Python?
return ends the function and sends a value back to the caller. Code after return never runs. A function without return gives None.
What are *args and **kwargs?
*args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dictionary. The names args and kwargs are convention, only the stars matter.
When should I use a lambda?
For short throwaway functions passed to sorted(), map(), filter() or GUI callbacks. If it needs a name or more than one expression, use def.