Skip to content
C

Functions

Defining and calling functions, parameters vs arguments, return values, default/positional/keyword arguments, *args and **kwargs, variable scope, lambdas, recursion, and the map/filter/reduce higher-order functions.


As programs grow, repeating the same block of code in multiple places becomes messy and hard to maintain. Functions let you package logic into a reusable, named block — write it once, use it as many times as you need.


1. What is a Function?

What is it?

A function is a named, reusable block of code that performs a specific task. You define it once and can "call" (run) it as many times as needed, from anywhere in your program.

Definition: A function is a reusable block of code designed to perform a specific task.

Why do we use it?

  • Avoid repetition — write logic once, reuse it everywhere.
  • Organize code — break a large program into smaller, understandable pieces.
  • Easier debugging — if something goes wrong, you know exactly which function to check.
  • Reusability across projects — well-written functions can be reused in other programs entirely.

How does it work?

You define a function using the def keyword, giving it a name and (optionally) inputs it needs. Later, you call the function by its name to actually run the code inside it.

Syntax

python
def function_name(parameters): # code to run return value # optional

Simple Example

python
def greet(): print("Hello! Welcome to Python.") greet() # calling the function greet() # can be called as many times as needed

Output:

Hello! Welcome to Python.
Hello! Welcome to Python.

Explanation of the Code

  • def greet(): defines a function named greet that takes no inputs.
  • The indented block is the function's body — the code that runs each time it's called.
  • greet() (with parentheses) is what actually executes it. Just writing greet without parentheses refers to the function itself, not a call to it.

Real-World Example

In a large application, a function like send_welcome_email(user) might be called every time a new user signs up — instead of rewriting the email logic at every signup point in the code.

Common Mistakes

  • Forgetting the parentheses when calling a function: greet vs greet() — only the second one actually runs the code.
  • Forgetting the colon : after the function definition line.
  • Incorrect indentation of the function body.

Important Points

  • Function names follow the same rules as variable names (snakecase is the Python convention: `calculatetotal, not CalculateTotal`).
  • A function must be defined before it is called in the code.

Practice

  1. Write a function say_hello() that prints a greeting message, and call it 3 times.

2. Parameters and Arguments

What is it?

  • A parameter is the name listed in the function's definition — a placeholder for a value the function expects.
  • An argument is the actual value you pass in when calling the function.

Simple Example

python
def greet(name): # "name" is a parameter print(f"Hello, {name}!") greet("Aditi") # "Aditi" is the argument greet("Rohan")

Output:

Hello, Aditi!
Hello, Rohan!

Explanation

  • name is just a placeholder in the definition — it has no value until the function is actually called.
  • Each call supplies a different argument, so the same function produces different, personalized output.

Common Mistakes

  • Calling a function without the required arguments: greet()TypeError: greet() missing 1 required positional argument: 'name'.
  • Using the words "parameter" and "argument" interchangeably in interviews — knowing the distinction is a common interview question.

Important Points

  • Parameters are defined; arguments are supplied at call time.
  • A function can have zero, one, or many parameters.

3. Return Values

What is it?

return sends a value back from the function to wherever it was called, so that value can be stored or used further.

Simple Example

python
def add(a, b): return a + b result = add(5, 3) print(result) # 8

Explanation

  • Unlike print(), which just displays something, return actually gives the value back to the caller so it can be stored in a variable (result) and used elsewhere in the program.
  • Once return runs, the function stops immediately — any code after return inside the function does not execute.

Common Mistakes

  • Confusing print() (just displays a value) with return (actually sends a value back for further use).
  • Forgetting a function without an explicit return returns None by default.
python
def add_no_return(a, b): print(a + b) # only displays, doesn't return anything result = add_no_return(3, 4) # prints "7" print(result) # None (nothing was returned!)

Important Points

  • A function can return any type: a number, string, list, dictionary, even another function.
  • return immediately exits the function.
  • No return statement means the function returns None.

Practice

  1. Write a function square(n) that returns the square of a number, and print the result for 3 different numbers.

4. Default Arguments

What is it?

A default argument provides a fallback value for a parameter, used only if the caller doesn't supply one.

Simple Example

python
def greet(name="Guest"): print(f"Hello, {name}!") greet() # Hello, Guest! greet("Aditi") # Hello, Aditi!

Common Mistakes

  • Placing a default parameter before a non-default one: def greet(name="Guest", age):SyntaxError. Default parameters must come after all non-default ones.
  • Using a mutable default value (like a list), which can cause unexpected shared behavior across calls (an advanced gotcha worth knowing).

Important Points

  • Default arguments make functions more flexible without requiring every caller to supply every value.
  • All non-default parameters must appear before any default parameters in the function definition.

5. Positional vs Keyword Arguments

What is it?

  • Positional arguments are matched to parameters based on their order.
  • Keyword arguments are matched by explicitly naming the parameter, regardless of order.

Simple Example

python
def describe_student(name, age, course): print(f"{name} is {age} years old, studying {course}") # Positional — order matters describe_student("Aditi", 21, "Computer Science") # Keyword — order doesn't matter describe_student(course="Computer Science", name="Aditi", age=21)

Both calls produce the same output:

Aditi is 21 years old, studying Computer Science

Common Mistakes

  • Mixing positional and keyword arguments incorrectly — positional arguments must always come before keyword arguments in a call: describe_student(name="Aditi", 21, "CS")SyntaxError.

Important Points

  • Keyword arguments improve readability, especially when a function has many parameters.
  • Positional arguments are simpler but require you to remember the exact order.

Practice

  1. Write a function with 3 parameters and call it once using positional arguments and once using keyword arguments.

6. *args and **kwargs

What is it?

  • *args lets a function accept any number of positional arguments, collected into a tuple.
  • **kwargs lets a function accept any number of keyword arguments, collected into a dictionary.

Simple Example — *args

python
def add_all(*numbers): return sum(numbers) print(add_all(1, 2, 3)) # 6 print(add_all(10, 20, 30, 40)) # 100

Explanation: *numbers gathers however many arguments are passed into a single tuple, e.g. (1, 2, 3), which sum() then adds together.

Simple Example — **kwargs

python
def print_profile(**details): for key, value in details.items(): print(f"{key}: {value}") print_profile(name="Aditi", age=21, course="CS")

Output:

name: Aditi
age: 21
course: CS

Explanation: **details gathers all keyword arguments into a dictionary, so any number of named values can be passed flexibly.

Real-World Example

Functions like Python's own print() accept a flexible number of arguments — this is exactly the kind of flexibility *args and **kwargs provide in your own functions.

Common Mistakes

  • Confusing the order of parameters — the correct order in a function definition is: normal parameters, then *args, then default parameters, then **kwargs.
  • Trying to access *args like a dictionary or **kwargs like a tuple — remember: args is a tuple, kwargs is a dictionary.

Important Points

  • The names args and kwargs are just convention — the * and ** are what matter, not the exact names.
  • *args → tuple of positional arguments. **kwargs → dictionary of keyword arguments.

Practice

  1. Write a function using *args that returns the maximum of any number of arguments passed in.
  2. Write a function using **kwargs that prints a formatted "profile card" from any number of named details.

7. Variable Scope

What is it?

Scope determines where in your program a variable can be accessed.

  • Local scope — a variable defined inside a function; only accessible within that function.
  • Global scope — a variable defined outside any function; accessible everywhere (including inside functions, for reading).

Simple Example

python
x = 10 # global variable def show_value(): y = 5 # local variable, only exists inside this function print(x, y) # can read global x, and its own local y show_value() print(x) # 10 — works, x is global print(y) # NameError! y only exists inside show_value()

Modifying a Global Variable Inside a Function

python
count = 0 def increment(): global count count += 1 increment() increment() print(count) # 2

Explanation: Without the global keyword, Python would treat count += 1 as creating a brand-new local variable inside the function, causing an error (since it's used before being assigned locally). global count tells Python to modify the actual global variable instead.

Common Mistakes

  • Trying to modify a global variable inside a function without using the global keyword, resulting in an UnboundLocalError.
  • Assuming a variable defined inside a function is accessible outside it — it isn't.

Important Points

  • Local variables only exist while their function is running.
  • Use the global keyword only when you genuinely need to modify a global variable from inside a function — overusing globals is generally considered poor practice.

Practice

  1. Create a global variable total = 0 and write a function that adds a number to it using the global keyword.

8. Lambda Functions

What is it?

A lambda is a small, anonymous (unnamed) function, written in a single line — used for short, simple operations, often passed directly into another function.

Syntax

python
lambda arguments: expression

Simple Example

python
square = lambda x: x ** 2 print(square(5)) # 25 add = lambda a, b: a + b print(add(3, 4)) # 7

Explanation

  • lambda x: x ** 2 is exactly equivalent to writing:
python
def square(x): return x ** 2

just in a shorter, single-line form.

Real-World Example

Lambdas are commonly used as a quick "key function" when sorting:

python
students = [("Aditi", 85), ("Rohan", 92), ("Zara", 78)] students.sort(key=lambda student: student[1]) print(students)

Output:

[('Zara', 78), ('Aditi', 85), ('Rohan', 92)]

Common Mistakes

  • Trying to write multi-line logic inside a lambda — lambdas can only contain a single expression, not full statements or multiple lines.
  • Overusing lambdas for complex logic, which hurts readability — use a regular def function when the logic is more than a simple one-liner.

Important Points

  • Lambdas have no name (unless assigned to a variable) and no return keyword — the expression's result is automatically returned.
  • Best used for short, throwaway functions, especially with sort(), map(), and filter().

Practice

  1. Write a lambda function that returns whether a number is even.
  2. Use a lambda to sort a list of words by their length.

9. Recursion

What is it?

Recursion is when a function calls itself to solve a smaller version of the same problem, until it reaches a simple "base case" that stops the recursion.

Simple Example — Factorial

python
def factorial(n): if n == 0 or n == 1: # base case return 1 return n * factorial(n - 1) # recursive case print(factorial(5)) # 120

Explanation of the Code

  • factorial(5) calls factorial(4), which calls factorial(3), and so on, down to factorial(1), which returns 1 (the base case).
  • The results then multiply back up the chain: 1 -> 2 -> 6 -> 24 -> 120.
  • Every recursive function must have a base case, or it will call itself forever, eventually crashing with a RecursionError.

Real-World Example

Recursion naturally fits problems with a repeating, self-similar structure — like navigating folders within folders, or calculating Fibonacci numbers.

python
def fibonacci(n): if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2) for i in range(7): print(fibonacci(i), end=" ")

Output:

0 1 1 2 3 5 8

Common Mistakes

  • Forgetting the base case, causing infinite recursion and a crash.
  • Using recursion for problems that would be simpler and more efficient with a plain loop.

Important Points

  • Every recursive function needs a base case (a stopping condition) and a recursive case (that moves toward the base case).
  • Recursion is elegant for tree-like or self-similar problems, but can be less efficient than loops for simple repetitive tasks.

Practice

  1. Write a recursive function to calculate the sum of numbers from 1 to n.
  2. Write a recursive function to reverse a string.

10. Higher-Order Functions: map, filter, reduce

What is it?

A higher-order function is a function that takes another function as an argument (or returns one). Python provides three especially useful built-in ones: map(), filter(), and reduce().

map() — Apply a Function to Every Item

python
numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x ** 2, numbers)) print(squared) # [1, 4, 9, 16, 25]

Explanation: map() applies the given function to every item in numbers, producing a new sequence of results.

filter() — Keep Only Items That Pass a Condition

python
numbers = [1, 2, 3, 4, 5, 6, 7, 8] evens = list(filter(lambda x: x % 2 == 0, numbers)) print(evens) # [2, 4, 6, 8]

Explanation: filter() keeps only the items for which the given function returns True.

reduce() — Combine All Items Into a Single Value

python
from functools import reduce numbers = [1, 2, 3, 4] total = reduce(lambda a, b: a + b, numbers) print(total) # 10

Explanation: reduce() repeatedly combines items two at a time: ((1 + 2) + 3) + 4 = 10. Unlike map() and filter(), reduce() must be imported from the functools module.

Comparison Table

FunctionPurposeReturns
map()Transform every itemNew sequence (same length)
filter()Keep items matching a conditionNew sequence (same or shorter length)
reduce()Combine all items into one valueA single value

Common Mistakes

  • Forgetting to wrap map()/filter() results in list(...) to actually see the values (they return special iterator objects, not lists directly).
  • Forgetting to import reduce from functools — unlike map/filter, it's not a built-in available by default.

Important Points

  • map(), filter(), and reduce() are often used with lambda functions for compact, one-line data processing.
  • They can often be replaced with list comprehensions, which many Python developers find more readable (e.g., [x**2 for x in numbers] instead of map()).

Practice

  1. Use map() to convert a list of Celsius temperatures to Fahrenheit.
  2. Use filter() to extract only the words longer than 4 letters from a list of words.
  3. Use reduce() to find the maximum value in a list without using the built-in max().

Common Beginner Mistakes — Summary for This Section

  • Confusing print() with return.
  • Forgetting a function without return gives back None.
  • Placing default parameters before non-default ones.
  • Forgetting the global keyword when modifying a global variable inside a function.
  • Writing recursive functions without a proper base case.

Cheat Sheet — Functions

python
def my_function(a, b=10, *args, **kwargs): return a + b my_function(5) # uses default b my_function(5, 20) # positional my_function(a=5, b=20) # keyword my_function(1, 2, 3, 4) # extra positional -> args my_function(1, x=5, y=10) # extra keyword -> kwargs square = lambda x: x ** 2 # lambda list(map(square, [1, 2, 3])) # map list(filter(lambda x: x > 1, [1, 2, 3])) # filter from functools import reduce reduce(lambda a, b: a + b, [1, 2, 3]) # reduce

Mini Project: Expense Tracker

Objective

Build a function-based command-line program that lets a user add expenses, view them, and see a running total.

Requirements

  • Store expenses as a list of dictionaries ({"category": ..., "amount": ...}).
  • Provide functions to add an expense, view all expenses, and calculate the total.
  • Use a loop to let the user keep adding expenses until they choose to stop.

Concepts Used

Functions, parameters/return values, lists, dictionaries, loops, conditionals.

Complete Code

python
expenses = [] def add_expense(category, amount): expenses.append({"category": category, "amount": amount}) print(f"Added: {category} - Rs.{amount}") def view_expenses(): if not expenses: print("No expenses recorded yet.") return for expense in expenses: print(f"{expense['category']}: Rs.{expense['amount']}") def calculate_total(): return sum(expense["amount"] for expense in expenses) while True: print("\n1. Add Expense 2. View Expenses 3. View Total 4. Exit") choice = input("Choose an option: ") if choice == "1": category = input("Category: ") amount = float(input("Amount: ")) add_expense(category, amount) elif choice == "2": view_expenses() elif choice == "3": print(f"Total Expenses: Rs.{calculate_total():.2f}") elif choice == "4": print("Goodbye!") break else: print("Invalid choice, try again.")

Code Explanation

  • Each menu option calls a dedicated function, keeping the main loop clean and readable.
  • calculate_total() uses a generator expression inside sum() to add up every expense's amount without needing a separate loop.
  • The while True loop keeps the menu running until the user selects "Exit."

Sample Output

1. Add Expense  2. View Expenses  3. View Total  4. Exit
Choose an option: 1
Category: Groceries
Amount: 1500
Added: Groceries - Rs.1500.0

1. Add Expense  2. View Expenses  3. View Total  4. Exit
Choose an option: 3
Total Expenses: Rs.1500.00

Possible Improvements

  • Add a function to delete or edit an existing expense.
  • Group and display expenses by category with subtotals.
  • Save expenses to a file so they persist after the program closes (covered in the File Handling section).

Challenge Task

Add a function that shows the total spent per category using a dictionary that accumulates totals as expenses are added.


Interview Questions

Q1. What is the difference between a parameter and an argument? Answer: A parameter is the variable name listed in a function's definition; an argument is the actual value passed in when the function is called.

*Q2. What's the difference between `args and kwargs`? Answer: *args collects extra positional arguments into a tuple. **kwargs collects extra keyword arguments into a dictionary.

Q3. What does a function return if there's no explicit `return` statement? Answer: None.

Q4. What is the difference between local and global scope? Answer: A local variable is defined inside a function and only accessible there. A global variable is defined outside any function and accessible throughout the program (though modifying it inside a function requires the global keyword).

Q5. What is a lambda function, and when would you use one? Answer: A small, anonymous, single-expression function, typically used for short operations passed into functions like sort(), map(), or filter().

Q6. What are the two essential parts of any recursive function? Answer: A base case (a condition that stops the recursion) and a recursive case (where the function calls itself with a smaller version of the problem).


Practice Questions

Beginner

  1. Write a function is_even(n) that returns True if a number is even.
  2. Write a function that takes a name and greets it with a default value of "Guest" if no name is passed.
  3. Write a function add(a, b, c) and call it using keyword arguments in a different order.
  4. Write a lambda function that multiplies two numbers.
  5. Write a function that returns the maximum of any number of arguments using *args.

Intermediate

  1. Write a recursive function to calculate the factorial of a number.
  2. Write a function that takes a list of numbers and returns a new list with only the even numbers, using filter().
  3. Write a function that takes a sentence and returns the number of vowels in it.
  4. Write a function using **kwargs that builds and returns a formatted string from any number of key-value details.
  5. Write a function that calculates simple interest, with default values for rate and time.

Challenge

  1. Write a recursive function to calculate the nth Fibonacci number, and compare its speed to an iterative version for large n.
  2. Write a function that takes a list of student dictionaries and returns the name of the student with the highest marks, using max() with a lambda key.
  3. Extend the Expense Tracker mini project to filter and display expenses above a certain amount, entered by the user.

Mock Test

  • Functions - Quick Test

    10 questions covering functions, parameters/arguments, return values, default/keyword arguments, *args/**kwargs, scope, lambdas, recursion and map/filter/reduce.

    10 questions · 10 min · Easy
    Start Mock Test

Coding Problems