python › functions
phoolchandra · Oct 23, 2026 · Published
Imagine writing the same 10 lines of code every time you want to calculate a student's percentage. Painful, right? Functions solve exactly this problem. They are the building blocks of every real Python program — from tiny scripts to Django websites and machine-learning pipelines.
In this guide you will learn functions from zero to interview-ready, with runnable examples, a "Predict the Output" quiz, practice challenges and a self-check list. Watch the video first, then use this blog as your notes.
How to use this blog: Open a Python shell (type python in your terminal) or any online Python editor and type every example yourself. Change the values, break the code, and see what happens. That is how functions really click.
A function is a block of statements that performs a specific task. You write it once, give it a name, and then call it whenever you need that task done. A function may or may not return a result.
Think of a function like a juicer machine: you put fruits in (input), the machine does its job (processing), and you get juice out (output). You don't rebuild the juicer every morning — you just use it again.
# Without a function: the same logic repeated again and again
marks1 = [78, 85, 90]
print("Average:", sum(marks1) / len(marks1))
marks2 = [60, 72, 81]
print("Average:", sum(marks2) / len(marks2))
# With a function: write once, reuse forever
def average(marks):
return sum(marks) / len(marks)
print("Average:", average([78, 85, 90])) # Average: 84.33333333333333
print("Average:", average([60, 72, 81])) # Average: 71.0This is the famous DRY principle — Don't Repeat Yourself.
def greet(name):
"""Greet a person by name."""
message = "Hello, " + name + "! Welcome to Coding Battle."
return message
print(greet("Aman"))
# Hello, Aman! Welcome to Coding Battle.| Part | Example | Meaning |
|---|---|---|
| def keyword | def | Tells Python you are defining a function |
| Function name | greet | Follows variable naming rules; use lowercase_with_underscores |
| Parameters | (name) | Placeholders for the input values (can be empty) |
| Colon | : | Marks the start of the function body |
| Docstring | """Greet a person...""" | Optional description; shown by help(greet) |
| Body | indented lines | The actual work — must be indented (4 spaces) |
| return | return message | Sends a value back to the caller and exits the function |
Remember: Defining a function does nothing by itself. The code inside runs only when you call it using its name followed by parentheses: greet("Aman").
These two words are often confused, and interviewers love asking about them:
def square(n): # n is a PARAMETER
return n * n
print(square(7)) # 7 is an ARGUMENT -> 49print() only shows a value on the screen. return gives the value back so you can store it and use it later. A function without a return statement automatically returns None.
def add_print(a, b):
print(a + b) # only displays
def add_return(a, b):
return a + b # gives the value back
x = add_print(2, 3) # prints 5
print(x) # None <-- surprise!
y = add_return(2, 3)
print(y * 10) # 50 <-- we can use the resultRule of thumb: If you will need the result later (to store, compare, or calculate), use return. Use print only to display things to the user.
Also note: return immediately exits the function. Any code after it is never executed.
def check_age(age):
if age >= 18:
return "Adult"
return "Minor" # runs only if the first return did not happen
print(check_age(20)) # Adult
print(check_age(15)) # MinorValues are matched to parameters by their position. Order matters!
def introduce(name, city):
print(name, "lives in", city)
introduce("Riya", "Delhi") # Riya lives in Delhi
introduce("Delhi", "Riya") # Delhi lives in Riya (wrong order!)Pass values using the parameter name. Now order does not matter and the call becomes self-explanatory.
introduce(city="Lucknow", name="Karan") # Karan lives in LucknowGive a parameter a default value. If the caller does not pass it, the default is used.
def power(base, exponent=2):
return base ** exponent
print(power(5)) # 25 (exponent defaults to 2)
print(power(2, 3)) # 8
print(power(exponent=3, base=2)) # 8Rule: Parameters with defaults must come after parameters without defaults. def f(a=1, b): is a SyntaxError.
The * collects all extra positional arguments into a tuple.
def total(*numbers):
print(type(numbers)) # <class 'tuple'>
return sum(numbers)
print(total(1, 2, 3)) # 6
print(total(10, 20, 30, 40)) # 100
print(total()) # 0The ** collects all extra keyword arguments into a dictionary.
def student_profile(**details):
for key, value in details.items():
print(key, ":", value)
student_profile(name="Riya", course="Python", level="Beginner")
# name : Riya
# course : Python
# level : Beginnerdef demo(a, b=10, *args, c, **kwargs):
print(a, b, args, c, kwargs)
demo(1, 2, 3, 4, c=5, x=6)
# 1 2 (3, 4) 5 {'x': 6}Order to remember: positional → default → *args → keyword-only → **kwargs. Here c comes after *args, so it can only be passed by keyword.
| Type | Syntax | Collected as | Use when |
|---|---|---|---|
| Positional | f(a, b) | individual values | Few required inputs |
| Keyword | f(b=2, a=1) | individual values | You want clarity / any order |
| Default | def f(a, b=2) | individual values | A parameter is usually the same |
| *args | def f(*args) | tuple | Unknown number of values |
| **kwargs | def f(**kwargs) | dict | Unknown number of named options |
This bug has confused even experienced developers. Default values are created only once — when the function is defined, not every time it is called.
def add_item(item, basket=[]):
basket.append(item)
return basket
print(add_item("apple")) # ['apple']
print(add_item("mango")) # ['apple', 'mango'] <-- unexpected!The fix: use None as the default and create a new list inside the function.
def add_item(item, basket=None):
if basket is None:
basket = []
basket.append(item)
return basket
print(add_item("apple")) # ['apple']
print(add_item("mango")) # ['mango'] <-- correctPython can return more than one value at once. Behind the scenes, it packs them into a tuple, which you can unpack directly.
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([4, 9, 1, 7])
print(low, high) # 1 9
print(min_max([4, 9, 1, 7])) # (1, 9)A variable created inside a function is local: it exists only while the function runs. A variable created outside all functions is global.
x = "global"
def show():
x = "local" # a NEW local variable, does not touch the global x
print(x)
show() # local
print(x) # globalTo modify a global variable inside a function, use the global keyword (use it sparingly — returning values is usually cleaner):
count = 0
def increment():
global count
count += 1
increment()
increment()
print(count) # 2Python looks for a name in this order, known as the LEGB rule:
| Letter | Scope | Example |
|---|---|---|
| L | Local | Variables inside the current function |
| E | Enclosing | Variables of an outer function (nested functions) |
| G | Global | Variables at the top level of the file |
| B | Built-in | print, len, sum, ... |
In Python, a function is just an object. You can store it in a variable, pass it to another function, or return it from a function. This idea powers decorators, callbacks and frameworks like Django.
def shout(text):
return text.upper()
def whisper(text):
return text.lower()
def speak(style, message):
return style(message) # calling the function that was passed in
print(speak(shout, "Hello")) # HELLO
print(speak(whisper, "Hello")) # hello
say = shout # assigning a function to a variable
print(say("python")) # PYTHONWant to go further? Read our blog on Decorators in Python in this same course — it builds directly on this concept.
A lambda is a small, one-line function without a name. Syntax: lambda arguments: expression.
square = lambda x: x * x
print(square(6)) # 36
nums = [1, 2, 3, 4, 5]
print(list(map(lambda x: x * x, nums))) # [1, 4, 9, 16, 25]
print(list(filter(lambda x: x % 2 == 0, nums))) # [2, 4]
students = [("Aman", 82), ("Riya", 95), ("Karan", 76)]
print(sorted(students, key=lambda s: s[1], reverse=True))
# [('Riya', 95), ('Aman', 82), ('Karan', 76)]Expert advice: Use lambdas for short, throw-away logic (like a key for sorting). If the logic needs more than one line or a name, write a normal def function.
A recursive function solves a problem by calling itself on a smaller version of the same problem. Every recursive function needs a base case to stop.
def factorial(n):
if n <= 1: # base case
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
# factorial(5) = 5 * 4 * 3 * 2 * 1Without a base case you get RecursionError: maximum recursion depth exceeded (Python's default limit is about 1000 calls).
def calculate_bmi(weight_kg: float, height_m: float) -> float:
"""Return the Body Mass Index rounded to 2 decimal places.
weight_kg: weight in kilograms
height_m: height in metres
"""
return round(weight_kg / height_m ** 2, 2)
print(calculate_bmi(70, 1.75)) # 22.86
help(calculate_bmi) # shows the docstringType hints (: float, -> float) do not change how the code runs, but they make your code self-documenting and help editors like VS Code catch mistakes early.
| Built-in functions | User-defined functions |
|---|---|
| Come ready-made with Python | Written by you using def |
| print(), len(), sum(), max(), input(), type() | average(), greet(), factorial() |
| Always available, no import needed | Available after the definition runs |
Don't run the code yet! Write down your answer for each question in a notebook, then check the Answers section at the end of this blog.
Q1.
def f(x):
x = x * 2
print(f(4))Q2.
def greet(name="Guest"):
return "Hi " + name
print(greet(), greet("Sam"))Q3.
def f(*args):
return len(args)
print(f(1, [2, 3], "four"))Q4.
x = 10
def change():
x = 20
change()
print(x)Q5.
def f(a, b=2, c=3):
return a + b * c
print(f(1, c=10))Q6. Will this code run?
def f(a=1, b):
return a + bSolve these in order — they go from easy to tricky. Hints are given in brackets.
Solutions for challenges 3, 4 and 6 are in the Answers section — try first, peek later!
Tick off each skill once you are confident:
Q: What is the difference between a function and a method?
A function is independent (len(s)). A method belongs to an object and is called on it (s.upper()).
Q: Does Python pass arguments by value or by reference?
Neither exactly — Python uses pass by object reference. Mutable objects (lists, dicts) changed inside a function are changed outside too; reassigning a variable inside the function does not affect the caller.
Q: What does a function return if there is no return statement?
None.
Q: What are *args and **kwargs?
*args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dictionary.
Q: Why should you avoid mutable default arguments?
Because the default object is created once and shared across all calls, so changes "leak" from one call to the next.
| Concept | Syntax / Key point |
|---|---|
| Define | def name(params): |
| Call | name(args) |
| Return value | return value (no return → None) |
| Default argument | def f(a, b=10) |
| Keyword argument | f(b=5, a=1) |
| Variable positional | *args → tuple |
| Variable keyword | **kwargs → dict |
| Multiple returns | return a, b → tuple |
| Modify global | global x |
| Lambda | lambda x: x * 2 |
| Docstring | """Explain the function""" |
# Challenge 3
def count_vowels(text):
count = 0
for ch in text.lower():
if ch in "aeiou":
count += 1
return count
print(count_vowels("Coding Battle")) # 4
# Challenge 4
def average(*nums):
if not nums:
return 0
return sum(nums) / len(nums)
print(average(10, 20, 30)) # 20.0
print(average()) # 0
# Challenge 6
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print([fibonacci(i) for i in range(8)]) # [0, 1, 1, 2, 3, 5, 8, 13]Functions turn messy, repeated code into clean, reusable building blocks. You now know how to define and call functions, use every type of argument, return values, handle scope, use lambdas and recursion, and avoid the classic traps. Next step: solve all six practice challenges, then move on to Decorators in Python and Object-Oriented Programming in this course.
If this blog helped you, watch the full video above, subscribe to the channel and share it with a friend who is learning Python. Happy coding!