Home Blogs All Courses
python c OA ( Online Assessment ) Amazon Web Services (AWS) leetcode dsa algorithms java Machine learning
Get Referral
Login Sign Up

Python Functions


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.

1. What is a Function?

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.

Why do we need functions?

  • Reusability – write once, use many times with different inputs.
  • Readability – calculate_tax(salary) is easier to understand than 15 lines of maths.
  • Easy debugging – if something breaks, you fix it in one place.
  • Teamwork – different people can write different functions of the same project.

Without functions vs with functions

# 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.0

This is the famous DRY principle — Don't Repeat Yourself.

2. Anatomy of a Python Function

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.
PartExampleMeaning
def keyworddefTells Python you are defining a function
Function namegreetFollows 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)
Bodyindented linesThe actual work — must be indented (4 spaces)
returnreturn messageSends 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").

3. Parameters vs Arguments

These two words are often confused, and interviewers love asking about them:

  • Parameter – the variable written in the function definition.
  • Argument – the actual value you pass while calling the function.
def square(n):        # n is a PARAMETER
    return n * n

print(square(7))      # 7 is an ARGUMENT  -> 49

4. return vs print — The #1 Beginner Mistake

print() 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 result

Rule 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))      # Minor

5. Types of Function Arguments

5.1 Positional arguments

Values 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!)

5.2 Keyword arguments

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 Lucknow

5.3 Default arguments

Give 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))  # 8

Rule: Parameters with defaults must come after parameters without defaults. def f(a=1, b): is a SyntaxError.

5.4 *args — any number of positional arguments

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())               # 0

5.5 **kwargs — any number of keyword arguments

The ** 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 : Beginner

5.6 The correct order of parameters

def 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.

TypeSyntaxCollected asUse when
Positionalf(a, b)individual valuesFew required inputs
Keywordf(b=2, a=1)individual valuesYou want clarity / any order
Defaultdef f(a, b=2)individual valuesA parameter is usually the same
*argsdef f(*args)tupleUnknown number of values
**kwargsdef f(**kwargs)dictUnknown number of named options

6. Expert Trap: Mutable Default Arguments

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']   <-- correct

7. Returning Multiple Values

Python 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)

8. Variable Scope — Local vs Global

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)      # global

To 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)  # 2

Python looks for a name in this order, known as the LEGB rule:

LetterScopeExample
LLocalVariables inside the current function
EEnclosingVariables of an outer function (nested functions)
GGlobalVariables at the top level of the file
BBuilt-inprint, len, sum, ...

9. Functions are First-Class Objects

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"))             # PYTHON

Want to go further? Read our blog on Decorators in Python in this same course — it builds directly on this concept.

10. Lambda (Anonymous) Functions

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.

11. Recursion — A Function Calling Itself

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 * 1

Without a base case you get RecursionError: maximum recursion depth exceeded (Python's default limit is about 1000 calls).

12. Write Functions Like a Pro: Docstrings & Type Hints

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 docstring

Type 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.

Best practices checklist

  • One function = one job. If the name needs "and", split it.
  • Use clear verb names: get_user(), calculate_total(), is_valid().
  • Prefer return over modifying global variables.
  • Keep functions short — ideally under 20–25 lines.
  • Never use a mutable object (list/dict) as a default value.

13. Built-in vs User-defined Functions

Built-in functionsUser-defined functions
Come ready-made with PythonWritten by you using def
print(), len(), sum(), max(), input(), type()average(), greet(), factorial()
Always available, no import neededAvailable after the definition runs

14. Quiz: Predict the Output

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 + b

15. Practice Challenges

Solve these in order — they go from easy to tricky. Hints are given in brackets.

  1. is_even(n) – return True if n is even, else False. (Hint: % operator)
  2. celsius_to_fahrenheit(c) – return the temperature in °F. (Hint: F = C × 9/5 + 32)
  3. count_vowels(text) – return how many vowels are in a string. (Hint: loop + in "aeiou")
  4. average(*nums) – return the average of any number of values; return 0 if nothing is passed.
  5. is_palindrome(word) – return True for words like "madam". (Hint: word[::-1])
  6. fibonacci(n) – return the nth Fibonacci number using recursion.

Solutions for challenges 3, 4 and 6 are in the Answers section — try first, peek later!

16. Self-Check: Can You Do This?

Tick off each skill once you are confident:

17. Frequently Asked Interview Questions

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.

18. Quick Revision Cheat Sheet

ConceptSyntax / Key point
Definedef name(params):
Callname(args)
Return valuereturn value (no return → None)
Default argumentdef f(a, b=10)
Keyword argumentf(b=5, a=1)
Variable positional*args → tuple
Variable keyword**kwargs → dict
Multiple returnsreturn a, b → tuple
Modify globalglobal x
Lambdalambda x: x * 2
Docstring"""Explain the function"""

Answers

Quiz answers

  1. None – the function has no return statement.
  2. Hi Guest Hi Sam – the default is used only when no argument is passed.
  3. 3 – the list [2, 3] counts as one argument.
  4. 10 – x = 20 created a new local variable.
  5. 21 – a=1, b=2 (default), c=10 → 1 + 2 × 10.
  6. No – SyntaxError: a parameter without a default cannot follow one with a default.

Challenge solutions

# 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]

Conclusion

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!