Learning Objectives – after this chapter you will be able to:
  • Define and call functions with def and return values with return.
  • Use positional, keyword, default, *args and **kwargs arguments.
  • Explain local and global scope.
  • Write lambda functions and simple recursive functions.
What is a Function?
  • A function is a named, reusable block of code that performs a specific task. It runs only when it is called.
  • Benefits: reusability (write once, use many times), modularity (break a big problem into small parts), easier testing and readability.
  • Built-in functions come with Python (print(), len(), max()); user-defined functions are written with def.
def function_name(parameters): """Docstring describing the function.""" statements return value
def area_of_rectangle(length, width):
    """Return the area of a rectangle."""
    return length * width

result = area_of_rectangle(8, 5)
print("Area:", result)
print(area_of_rectangle.__doc__)
Output
Area: 40
Return the area of a rectangle.

Parameters are the names in the definition (length, width); arguments are the actual values passed in the call (8, 5).

Return Values
  • return ends the function and sends a value back to the caller.
  • A function without return (or with a bare return) returns None.
  • A function can return several values as a tuple.
def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([12, 4, 25, 9])
print(low, high)

def greet(name):
    print("Hello", name)      # prints, but returns nothing

value = greet("Kiran")
print(value)
Output
4 25
Hello Kiran
None
Types of Arguments
TypeDescription
PositionalMatched to parameters by their order.
KeywordPassed as name=value; order does not matter.
DefaultParameter has a default value used when the argument is omitted.
*argsCollects any number of extra positional arguments into a tuple.
**kwargsCollects any number of extra keyword arguments into a dictionary.
def make_bill(item, price, qty=1, discount=0):
    return f"{item}: {price * qty - discount}"

print(make_bill("Pen", 10))                    # positional + defaults
print(make_bill("Book", 250, qty=2))           # keyword argument
print(make_bill(price=40, item="Ink", discount=5))

def total(*args):
    return sum(args)
print(total(1, 2, 3, 4))

def profile(**kwargs):
    for key, value in kwargs.items():
        print(key, "=", value)
profile(name="Asha", city="Bhopal")
Output
Pen: 10
Book: 500
Ink: 35
10
name = Asha
city = Bhopal
Do not use a mutable object (such as a list) as a default value. The default is created once, when the function is defined, so it is shared between calls. Use None and create the list inside the function.
The mutable default argument trap
def add_item_wrong(item, basket=[]):
    basket.append(item)
    return basket

print(add_item_wrong("a"))
print(add_item_wrong("b"))     # the same list is reused!

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

print(add_item("a"))
print(add_item("b"))
Output
['a']
['a', 'b']
['a']
['b']
Scope: Local and Global Variables
  • A variable created inside a function is local – it exists only while the function runs.
  • A variable created outside all functions is global – it can be read inside functions.
  • To assign to a global variable inside a function, declare it with global. Python looks up names in the order Local → Enclosing → Global → Built-in (LEGB).
counter = 0                  # global

def increase():
    global counter
    counter += 1

def show():
    message = "local text"   # local
    print(message, counter)

increase()
increase()
show()
Output
local text 2
Lambda Functions

A lambda is a small anonymous function written in one expression: lambda parameters: expression. It is often passed to functions such as sorted(), map() and filter().

square = lambda x: x * x
print(square(6))

nums = [5, 12, 7, 20]
print(list(map(lambda n: n * 2, nums)))
print(list(filter(lambda n: n > 6, nums)))

students = [("Asha", 82), ("Ravi", 67), ("Meera", 91)]
print(sorted(students, key=lambda s: s[1], reverse=True))
Output
36
[10, 24, 14, 40]
[12, 7, 20]
[('Meera', 91), ('Asha', 82), ('Ravi', 67)]
Recursion

A recursive function calls itself. Every recursive function needs a base case that stops the recursion; otherwise Python raises RecursionError (the default depth limit is about 1000 calls).

def factorial(n):
    if n <= 1:            # base case
        return 1
    return n * factorial(n - 1)

def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(factorial(5))
print([fibonacci(i) for i in range(10)])
Output
120
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Key Takeaways
  • Define with def, call with name(args); no return means None.
  • *args → tuple, **kwargs → dict; avoid mutable default values.
  • Names resolve by LEGB; recursion needs a base case.
Video : Functions
Question / Answer (15 questions)

Answer : A function is a named, reusable block of code that performs a specific task when called. Advantages: code reusability, modularity (breaking a problem into parts), easier testing and debugging, and better readability.

Answer : Parameters are the variable names listed in the function definition. Arguments are the actual values passed to the function when it is called. In def add(a, b) and add(2, 3), a and b are parameters while 2 and 3 are arguments.

Answer : It returns None.

Answer : By returning several values separated by commas, which Python packs into a tuple: return low, high. The caller can unpack them: low, high = min_max(nums).

Answer : Default arguments have a value in the definition that is used when the caller omits them. In def make_bill(item, price, qty=1), calling make_bill("Pen", 10) uses qty = 1.

Answer : Keyword arguments are passed as name=value, so their order does not matter and calls become self-explanatory, e.g. make_bill(price=40, item="Ink").

Answer : *args collects any number of extra positional arguments into a tuple. **kwargs collects any number of extra keyword arguments into a dictionary. They let a function accept a variable number of arguments.

Answer : Default values are evaluated once, when the function is defined, so the same list object is shared by every call and changes accumulate between calls. Use None as the default and create a new list inside the function.

Answer : A local variable is created inside a function and exists only during that call. A global variable is defined at the top level of a module and can be read anywhere in it. Assigning to a global inside a function requires the global keyword.

Answer : It is the order in which Python looks up a name: Local scope, then Enclosing function scopes, then Global (module) scope, then Built-in names.

Answer : A lambda is a small anonymous function defined with the lambda keyword and a single expression, e.g. lambda x: x * x. It is commonly used as a short argument to functions like sorted(), map() and filter().

Answer : map(func, iterable) applies func to every item and returns an iterator of the results. filter(func, iterable) returns an iterator of only those items for which func returns a truthy value.

Answer : Recursion is when a function calls itself to solve a smaller version of the same problem. The base case is the condition under which the function returns without calling itself, which stops the recursion.

Answer : It keeps calling itself until Python’s recursion limit (about 1000 calls by default) is exceeded, and a RecursionError is raised.

Answer : A docstring is a string literal written as the first statement inside a function, describing what it does. It can be read with function_name.__doc__ or help(function_name).
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which keyword is used to define a function in Python?

Show Answer

Correct Answer : B. def
Functions are defined with def.

Q2. Inside def f(*args):, what is the type of args?

Show Answer

Correct Answer : A. tuple
*args collects extra positional arguments into a tuple.

Q3. What is printed by: def f(): pass – then print(f())?

Show Answer

Correct Answer : D. None
A function without return returns None.

Q4. What is the output of print((lambda x, y: x * y)(3, 4))?

Show Answer

Correct Answer : C. 12
The lambda multiplies its two arguments: 3 × 4 = 12.

Q5. Which keyword lets a function assign to a module-level variable?

Show Answer

Correct Answer : A. global
global declares that the name refers to the module-level variable.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Python Software Foundation. (n.d.). More Control Flow Tools. In The Python Tutorial. https://docs.python.org/3/tutorial/controlflow.html
  2. Python Software Foundation. (n.d.). Execution Model (Naming and Binding). In The Python Language Reference. https://docs.python.org/3/reference/executionmodel.html
  3. Python Software Foundation. (n.d.). Built-in Functions. The Python Standard Library. https://docs.python.org/3/library/functions.html
  4. Goodger, D., & van Rossum, G. (2001). PEP 257 – Docstring Conventions. Python Enhancement Proposals. https://peps.python.org/pep-0257/
  5. Python Software Foundation. (n.d.). Glossary. Python 3 Documentation. https://docs.python.org/3/glossary.html
  6. Lutz, M. (2013). Learning Python (5th ed.). O’Reilly Media.
  7. Downey, A. B. (2024). Think Python (3rd ed.). O’Reilly Media. (Free online edition by Green Tea Press.) https://allendowney.github.io/ThinkPython/