What are Functions in Python?
Functions are reusable blocks of code that perform a specific task. They help you organise code, avoid repetition, and make programs easier to understand and maintain.
Contents
Why use functions?
Functions let you write code once and use it multiple times. Instead of repeating the same logic, you define it once and call it whenever needed.
# Without functions - repetitive code
numbers1 = [1, 2, 3, 4, 5]
total1 = 0
for num in numbers1:
total1 += num
print(total1)
>>> 15
numbers2 = [10, 20, 30]
total2 = 0
for num in numbers2:
total2 += num
print(total2)
>>> 60
With functions, you define the logic once and reuse it.
# With functions - reusable code
def calculate_sum(numbers):
total = 0
for num in numbers:
total += num
return total
print(calculate_sum([1, 2, 3, 4, 5]))
>>> 15
print(calculate_sum([10, 20, 30]))
>>> 60
Functions also make code more readable by giving operations clear names.
# Clear intent with function names
def is_even(number):
return number % 2 == 0
def get_discount_price(price, discount_percent):
return price * (1 - discount_percent / 100)
print(is_even(8))
>>> True
print(get_discount_price(100, 20))
>>> 80.0
How functions work
A function takes input (parameters), performs operations, and optionally returns output. Think of it as a machine: you feed it inputs, it processes them, and gives you a result.
def greet(name):
message = f"Hello, {name}!"
return message
result = greet("Alice")
print(result)
>>> Hello, Alice!
Functions can work without parameters or return values.
def say_hello():
print("Hello, World!")
say_hello()
>>> Hello, World!
# This function doesn't return anything (returns None)
result = say_hello()
print(result)
>>> Hello, World!
>>> None
Function components
A function definition has several parts: the def keyword, function name, parameters, and body.
def multiply(a, b): # Function definition
"""Multiply two numbers and return the result."""
result = a * b # Function body
return result # Return statement
product = multiply(5, 3) # Function call
print(product)
>>> 15
The function name should describe what it does. Parameters are placeholders for values passed when calling the function.
def calculate_area(length, width):
"""Calculate the area of a rectangle."""
return length * width
area = calculate_area(5, 3)
print(area)
>>> 15
Functions can have default parameter values, making some arguments optional.
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice"))
>>> Hello, Alice!
print(greet("Bob", "Hi"))
>>> Hi, Bob!
Types of functions
Python has several types of functions, each suited to different tasks.
Built-in functions
Python provides many built-in functions that are always available, like 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]
See Python Built-in Functions for a comprehensive guide.
User-defined functions
You create user-defined functions with the def keyword. They're the most common way to organise your code.
def calculate_total(price, tax_rate=0.20):
return price * (1 + tax_rate)
print(calculate_total(100))
>>> 120.0
See User-Defined Functions in Python for details on creating custom functions.
Anonymous functions
Anonymous functions, created with lambda, don't have names. They're useful for short operations.
square = lambda x: x ** 2
print(square(5))
>>> 25
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
>>> [1, 4, 9, 16, 25]
See Anonymous Functions in Python for more on lambda functions.
Recursive functions
Recursive functions call themselves to solve problems by breaking them into smaller subproblems.
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5))
>>> 120
See Recursive Functions in Python for more on recursion.
Generator functions
Generator functions use yield to produce values lazily, making them memory-efficient for large sequences.
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
See Generator Functions in Python for more on generators.
Higher-order functions
Higher-order functions take other functions as arguments or return functions.
def apply_operation(x, y, operation):
return operation(x, y)
def add(a, b):
return a + b
print(apply_operation(5, 3, add))
>>> 8
See Higher-Order Functions in Python for more on this pattern.
For a complete overview of all function types, see What are the Types of Functions in Python?.
Calling functions
To use a function, you call it by name and provide arguments (if required).
def add(a, b):
return a + b
# Call with positional arguments
result = add(3, 5)
print(result)
>>> 8
# Call with keyword arguments
result = add(a=3, b=5)
print(result)
>>> 8
You can mix positional and keyword arguments, but positional arguments must come first.
def create_profile(name, age, city):
return f"{name}, {age}, from {city}"
print(create_profile("Alice", age=25, city="London"))
>>> Alice, 25, from London
Functions can accept variable numbers of arguments using *args and **kwargs.
def sum_all(*args):
return sum(args)
print(sum_all(1, 2, 3, 4, 5))
>>> 15
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)
>>> name: Alice
>>> age: 25