Functions in Python: definition, parameters, and value return
Functions in Python are blocks of code that perform certain tasks and make the program more modular and readable. The functions allow you to avoid code repetition and simplify its testing and maintenance.
How to create a function in Python
Functions in Python are defined using the keyword def, followed by the function name, parameters in parentheses, and a colon. The function body must be indented.:
def function_name(parameters):
# the body
of the pass function
Example of the simplest function:
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!
Parameters and arguments of functions
Functions can take various types of parameters, which makes them flexible and versatile.
Required parameters
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
Default settings
If no argument is passed, a predefined value is used.:
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Alice") # Hello, Alice!
greet("Bob", "Hi") # Hi, Bob!
Named arguments
Arguments can be passed by name, which makes the code clearer.:
def descripe_pet(pet_name, animal_type="dog"):
print(f"I have an {animal_type} named {pet_name}.")
descripe_pet(pet_name="Willy") # I have a dog named Willy.
descripe_pet(animal_type="cat", pet_name="Whiskers") # I have a cat named Whiskers.
Variable-length arguments
*argsfor positional arguments of variable length**kwargsfor named arguments of variable length
def make_pizza(size, *toppings):
print(f"\n Cooking a {size} inch pizza with the following fillings:")
for topping in toppings:
print(f"- {topping}")
make_pizza(12, "pepperoni", "mushrooms", "green peppers")
def build_profile(first, last, **user_info):
profile = {"first_name": first, "last_name": last}
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile("albert", "einstein", location="princeton", field="physics")
print(user_profile)
# {'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
Returning values from functions
The function can return a value using the return operator:
def square(x):
return x ** 2
result = square(4)
print(result) # 16
Documentation of functions (docstrings)
Documentation strings are used to describe the function's purpose.:
def greet(name):
"""Outputs a welcome message with the name."""
print(f"Hello, {name}!")
print(greet.__doc__) # Displays a welcome message with the name.
Recursion in Python: principles and examples
Recursion is a programming method in which a function calls itself. Each recursive function must have a base case and a recursive case.
The factorial of a number
The factorial of a number n (n!) is the product of all positive integers from 1 to n:
def factorial(n):
"""Returns the factorial of the number n."""
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 120
Fibonacci numbers
The Fibonacci sequence - each number is equal to the sum of the previous two:
def fibonacci(n):
"""Returns the nth Fibonacci number."""
if n<= 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(6)) # 8
Recursion constraints
Python has a limit on the depth of recursion (usually 1000 calls):
import sys
print(sys.getrecursionlimit()) # 1000
sys.setrecursionlimit(1500)
Tail recursion
Tail recursion is a recursion where a recursive call is the last action.:
def factorial_tail_recursive(n, accumulator=1):
"""Returns the factorial of the number n using tail recursion."""
if n == 0:
return accumulator
else:
return factorial_tail_recursive(n - 1, n * accumulator)
print(factorial_tail_recursive(5)) # 120
Alternatives to recursion: iterative approaches
Iterative factorial
def factorial_iterative(n):
"""Calculates the factorial iteratively."""
result = 1
for i in range(1, n + 1):
result *= i
return result
print(factorial_iterative(5)) # 120
Iterative Fibonacci numbers
def fibonacci_iterative(n):
"""Calculates the Fibonacci number iteratively."""
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
print(fibonacci_iterative(6)) # 8
Advanced techniques for working with functions
Lambda functions
Lambda functions are anonymous functions for simple operations:
square = lambda x: x ** 2
print(square(5)) # 25
sum_two = lambda a, b: a + b
print(sum_two(3, 4)) # 7
Higher-order functions
Functions that take other functions as arguments:
def apply_function(func, value):
"""Applies a function to a value."""
return func(value)
print(apply_function(square, 5)) # 25
Decorators
Decorators allow you to wrap one function in another, changing its behavior:
def decorator(func):
"""Decorator for logging function calls."""
def wrapper():
print("Something happens before the function is called.")
func()
print("Something happens after function call.")
return wrapper
@decorator
def say_hello():
print("Hello!")
say_hello()
Short circuits
Closures are functions that "remember" the context of their creation:
def outer_function(x):
"""An external function that creates a closure."""
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # 15
When to use recursion
Recursion is especially useful for:
- Processing of tree-like data structures
- Solving problems that can be divided into subtasks
- Implementations of divide-and-conquer algorithms
- Working with mathematical sequences
Recommendations for use
- Use functions to avoid code duplication
- Choose iteration instead of recursion for simple tasks
- Use recursion for complex data structures
- Document the functions using docstrings
- Test functions in isolation for better debugging
Understanding functions and recursion is the foundation for writing efficient and readable Python code. These tools help you create modular programs that are easy to maintain and extend.