Python Functions
In Python, a function is a group of related statements that performs a specific task. Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organized and manageable. It avoids repetition and makes the code reusable. The syntax of functions is:
def function_name(parameters):
"""docstring"""
statement(s)
return expression
Function definition that consists of the following components:
- Keyword
defthat marks the start of the function header. - A function name to uniquely identify the function. Function naming follows the same rules of writing identifiers in Python.
- Parameters (arguments) through which we pass values to a function. They are optional.
- A colon (
:) to mark the end of the function header. - Documentation string (docstring) to describe what the function does which is optional.
- One or more valid python statements that make up the function body. Statements must have the same indentation level (usually 4 spaces).
- Return statement to return a value from the function which is optional.
To call a function in Python: To call a function in python first we have to define the function, we can call it from another function, program or even the Python prompt. To call a function we simply type the function name with appropriate parameters.
Example:
def greet(name):
""" This function greets to the person passed in as a parameter """
print("Hello, " + name + ". Good morning!")
greet('Developer')
Output:
Hello, Developer. Good morning!
Docstrings
The first string after the function header is called the docstring and is short for documentation string. It is briefly used to explain what a function does. Python docstrings are the string literals that appear after the definition of a method, class, or module also. We generally use triple quotes so that docstring can extend up to multiple lines. We can access these doc strings using the __doc__ attribute.
Example:
def greet(name):
""" This function greets to the person passed in as a parameter """
print("Hello, " + name + ". Good morning!")
print(greet.__doc__)
Output:
This function greets to the person passed in as a parameter
Using the help() Function for Docstrings: We can also use the help() function to read the doc strings associated with various objects. Here, we can see that the help() function retrieves the doc strings of the Person class along with the methods associated with that class.
Example:
def greet(name):
""" This function greets to the person passed in as a parameter """
print("Hello, " + name + ". Good morning!")
help(greet)
Output:
Help on function greet in module __main__:
greet(name)
This function greets to the person passed in as a parameter
The Return Statement
The return statement is used to exit a function and go back to the place from where it was called. This statement can contain an expression that gets evaluated and the value is returned. If there is no expression in the statement or the return statement itself is not present inside a function, then the function will return the None object. The syntax of return is return [expression_list].
Example:
def greet(name):
""" This function greets to the person passed in as a parameter """
print("Hello, " + name + ". Good morning!")
print(greet("Developer"))
Output:
Hello, Developer. Good morning!
None
Here, None is the returned value since greet() directly prints the name and no return statement is used.
Example:
def mul_value(num):
"""This function returns the multiplication value of the entered number"""
return num * 5
print(mul_value(2))
Output:
10
Function Arguments
Python offers 7 types of arguments, giving you great flexibility in how you pass data to functions.
1. Positional Arguments
The most basic type — values are assigned to parameters in order.
def add(a, b):
return a + b
print(add(3, 5)) # a=3, b=5
Output:
8
⚠️ Order matters — swapping values changes the result.
2. Keyword Arguments
Pass arguments by name, so order doesn't matter.
def introduce(name, age):
print(f"I'm {name}, aged {age}")
introduce(age=25, name="Alice")
Output:
I'm Alice, aged 25
3. Default Arguments
Parameters with pre-set values — used when the caller doesn't provide them.
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Bob") # Output: Hello, Bob!
greet("Bob", "Hi") # Output: Hi, Bob!
⚠️ Default arguments must come after non-default ones.
4. `*args` — Variable Positional Arguments
Accepts any number of positional arguments as a tuple.
def total(*args):
return sum(args)
print(total(1, 2, 3)) # Output: 6
print(total(10, 20, 30, 40)) # Output: 100
You can iterate over args like any tuple:
def show(*args):
for i, val in enumerate(args):
print(f" arg[{i}] = {val}")
show("apple", "banana", "cherry")
Output:
arg[0] = apple
arg[1] = banana
arg[2] = cherry
5. `**kwargs` — Variable Keyword Arguments
Accepts any number of keyword arguments as a dictionary.
def profile(**kwargs):
for key, value in kwargs.items():
print(f" {key}: {value}")
profile(name="Alice", age=30, city="Hyderabad")
Output:
name: Alice
age: 30
city: Hyderabad
6. Keyword-Only Arguments
Arguments that must be passed by keyword (placed after * or *args).
def create_user(name, *, role="user", active=True):
print(f"{name} | Role: {role} | Active: {active}")
create_user("Alice", role="admin") # ✅ Works
create_user("Alice", "admin") # ❌ TypeError
7. Positional-Only Arguments
Arguments that must be passed positionally (placed before /). Introduced in Python 3.8.
def power(base, exp, /):
return base ** exp
power(2, 10) # ✅ Works → 1024
power(base=2, exp=10) # ❌ TypeError
Function Types in Python
Python has several types of functions, each suited for different use cases.
1. Built-in Functions
Pre-defined functions that come with Python — no import needed.
print("Hello") # Output: Hello
len([1, 2, 3]) # Output: 3
max(10, 20, 5) # Output: 20
type(3.14) # Output: <class 'float'>
2. User-defined Functions
Functions you create using the def keyword.
def greet(name):
return f"Hello, {name}!"
print(greet("Alice")) # Output: Hello, Alice!
3. Lambda Functions (Anonymous Functions)
Single-expression functions defined with lambda. Great for short, throwaway logic.
square = lambda x: x ** 2
print(square(5)) # Output: 25
# Common use: sorting
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
students.sort(key=lambda s: s[1])
print(students) # Sorted by score
4. Recursive Functions
Functions that call themselves to solve problems by breaking them into smaller subproblems.
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print(factorial(5)) # Output: 120
5. Higher-Order Functions
Functions that take other functions as arguments or return them. map(), filter(), and reduce() are classic examples.
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
total = reduce(lambda x, y: x + y, numbers)
print(total) # 15
6. Generator Functions
Use yield instead of return to produce values lazily (one at a time), saving memory.
def count_up(n):
for i in range(1, n + 1):
yield i
for val in count_up(5):
print(val) # Prints 1, 2, 3, 4, 5 one at a time
7. Nested Functions (Inner Functions)
Functions defined inside another function. The inner function has access to the outer function's variables.
def outer(message):
def inner():
print(f"Message: {message}") # Accesses outer's variable
inner()
outer("Hello!") # Output: Message: Hello!