What are the Types of Functions in Python?
Functions are an essential part of every programming language. In Python, they are usually grouped as either built-in functions or user-defined functions.
Start by reading What are Functions in Python? to learn more about functions in Python.
Contents
Built-in functions
Built-in functions come ready to use in Python, so you do not need to import anything to access them. Examples include len(), print(), max(), and sorted().
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(len(numbers))
>>> 8
print(max(numbers))
>>> 9
print(sorted(numbers))
>>> [1, 1, 2, 3, 4, 5, 6, 9]
You can use dir(__builtins__) to see all the built-in functions in Python. There are over 70 of them. For a full list, check out this list of all built-in functions.
User-defined functions
User-defined functions are created by developers using certain keywords and patterns. You can write basic functions with def, and there are also special types like recursive functions, anonymous functions, higher-order functions, and generator functions.
Basic user-defined functions
Basic user-defined functions are created using the def keyword. They're the most common way to organise code and create reusable logic.
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))
>>> Hello, Alice!
Functions may accept different types of parameters, such as keyword, positional, default, arbitrary positional, and arbitrary keyword arguments. Check types of Python function arguments for more information.
def calculate_total(price, tax_rate=0.20, discount=0):
subtotal = price * (1 - discount)
return subtotal * (1 + tax_rate)
print(calculate_total(100))
>>> 120.0
print(calculate_total(100, tax_rate=0.15, discount=0.1))
>>> 103.5
Recursive functions
Recursive functions call themselves to solve problems by breaking them into smaller subproblems. They're useful for tasks like traversing trees or calculating factorials. They need a base case to prevent infinite recursion.
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
>>> 120
Anonymous functions
Anonymous functions, created with lambda, don't have a name. They're useful for short operations, especially with functions like map(), filter(), and sorted().
square = lambda x: x ** 2
print(square(5))
>>> 25
Lambda functions can also take multiple arguments but are limited to a single expression. Check anonymous functions (lambda) in Python for more information. They're particularly handy with built-in functions that take a function as an argument.
add = lambda x, y: x + y
print(add(3, 7))
>>> 10
Higher-order functions
Higher-order functions either take other functions as arguments or return functions. Python treats functions as first-class objects, making this straightforward.
def apply_operation(x, y, operation):
return operation(x, y)
def add(a, b):
return a + b
def multiply(a, b):
return a * b
print(apply_operation(5, 3, add))
>>> 8
print(apply_operation(5, 3, multiply))
>>> 15
You can use higher-order functions together with decorators to handle cross-cutting concerns. For examples of how to use decorators, see higher-order functions in Python.
def log_calls(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@log_calls
def add(a, b):
return a + b
print(add(3, 4))
>>> Calling add with (3, 4), {}
>>> add returned 7
>>> 7
Generator functions
Generator functions use yield instead of return to produce values lazily. They're memory-efficient for large sequences and create iterator objects.
def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1
for num in count_up_to(5):
print(num)
>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
Generator functions use yield instead of return to produce values one at a time as needed. This makes them memory-efficient for handling large sequences and allows them to create iterator objects. For more details, see generator functions in Python.
def fibonacci_generator():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci_generator()
print([next(fib) for _ in range(10)])
>>> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]