Skip to main content

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.

New in Python?

Start by reading What are Functions in Python? to learn more about functions in Python.

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().

Example 1
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.

Example 4
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.

Example 5
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.

Example 7
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().

Example 10
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.

Example 11
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.

Example 13
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.

Example 15
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.

Example 16
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.

Example 17
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]

See also