What Is a Function?
A function is a reusable block of code that performs a specific task.
For example, if you often need to print a greeting, you could put that code inside a function.
def greet():
print("Hello!")Now you can use that function whenever you want:
greet()
greet()
greet()
# Output:
# Hello!
# Hello!
# Hello!Instead of writing the same print() statement three times, we wrote it once and reused it.
Creating a Function
We use the def keyword to create a function.
The basic syntax is:
def function_name():
# code to runFor example:
def greet():
print("Hello!")Here:
deftells Python that we’re creating a function.greetis the name of the function.()comes after the function name.
The indented code is the function body.
Calling a Function
Creating a function doesn’t run the code inside it.
To run the function, you need to call it.
def greet():
print("Hello!")
greet()
# Output:
# Hello!The line: greet() is what actually runs the code inside the function.
Think of it like this:
- Define the function → create it
- Call the function → run it
You can call the same function multiple times:
def greet():
print("Hello!")
greet()
greet()
greet()
# Output:
# Hello!
# Hello!
# Hello!What Does a Function Return?
So far, our greet() function only prints a message:
def greet():
print("Hello!")
result = greet()
print(result)
# Output:
# Hello!
# NoneWhy does result contain None?
Because greet() doesn’t explicitly return a value.
Remember print()? print() also returns None.
The same thing happens with a function that doesn’t have a return statement.
We’ll learn how to make a function return a real value later in this lesson.
Function Names
Just like variables, function names should be descriptive and follow Python’s naming rules.
For example:
def say_hello():
print("Hello!")
def show_profile():
print("Profile")
def calculate_total():
print("Calculating...")Using a name that describes what the function does makes your code easier to understand.
Functions We’ve Already Used
We’ve actually been using functions in the earlier lessons as well.
For example:
print("Hello")Here, print() is a Python built-in function.
We’ve also used:
input("Enter your name: ")
len("Python")
int("10")These are all built-in functions provided by Python.
We don’t have to create them ourselves.
Now, we’re learning how to create our own user-defined functions.
Built-in vs User-Defined Functions
There are two basic types of functions you’ll come across:
Built-in Functions
These are already provided by Python.
Examples:
print()
input()
len()
int()
float()User-Defined Functions
These are functions that you create yourself using def.
For example:
def greet():
print("Hello!")This is a user-defined function.
A Function Can Contain More Than One Line
A function can contain multiple lines of code.
For example:
def show_profile():
print("--- Profile ---")
print("Name: Shefali")
print("City: Delhi")Call it:
show_profile()
# Output:
# --- Profile ---
# Name: Shefali
# City: DelhiAll the indented lines belong to the function.
This is another reason functions are useful: you can group related code together.
Indentation Matters
Just like with if statements and loops, indentation tells Python which code belongs to the function.
# Correct:
def greet():
print("Hello!")
# Incorrect:
def greet():
print("Hello!")The second example causes an indentation error because the function body isn’t indented.
Why Use Functions?
Functions help you:
- Reuse code
- Avoid repeating the same code
- Break a large program into smaller pieces
- Keep your code organized
- Make your code easier to read and maintain
- As your programs get bigger, these benefits become more important.
What Is a Parameter?
A parameter is a variable that you define inside the parentheses when creating a function.
For example:
def greet(name):
print("Hello", name)Here, name is a parameter.
It gives the function a way to receive information.
Now we can call the function with different names:
greet("Shefali")
greet("John")
# Output:
# Hello Shefali
# Hello JohnThe function stays the same, but the information it works with changes.
What Is an Argument?
An argument is the actual value you pass to a function when you call it.
In this example:
greet("Shefali")"Shefali" is the argument.
So:
def greet(name):,name→ parametergreet("Shefali"), "Shefali" → argument
A simple way to remember it:
- Parameter: The variable in the function definition.
- Argument: The value you pass when calling the function.
A Function With Multiple Parameters
A function can have more than one parameter.
For example:
def greet(first_name, city):
print("Hello", first_name)
print("You are from", city)Now we can provide both values:
greet("Shefali", "Delhi")
# Output:
# Hello Shefali
# You are from DelhiHere:
first_nameis the first parameter.cityis the second parameter.- "Shefali" is the first argument.
- "Delhi" is the second argument.
Positional Arguments
When you pass arguments normally, Python matches them to the parameters based on their position.
For example:
def greet(first_name, city):
print("Hello", first_name)
print("You are from", city)
greet("Shefali", "Delhi")Python matches them like this:
first_name→ “Shefali”city→ “Delhi”
The first argument goes to the first parameter and the second argument goes to the second parameter.
That’s why these are called positional arguments.
Order Matters
Because Python matches positional arguments by position, the order matters.
For example:
def introduce(name, age):
print("Name:", name)
print("Age:", age)
introduce("Shefali", 27)
# Output:
# Name: Shefali
# Age: 27But if we change the order: introduce(27, "Shefali")
Python doesn’t know that we meant to put the name first.
It simply follows the positions:
name→ 27age→ “Shefali”
The function receives the values in the order we provide them.
Keyword Arguments
You can also pass arguments by naming the parameter directly.
These are called keyword arguments.
For example:
def introduce(name, age):
print("Name:", name)
print("Age:", age)
introduce(age=27, name="Shefali")
# Output:
# Name: Shefali
# Age: 27Notice that we passed age first and name second.
This works because Python matches the values by parameter name instead of position.
So with keyword arguments, the order doesn’t matter.
This can be especially useful when a function has several parameters and you want to make it clear which value belongs to which parameter.
Mixing Positional and Keyword Arguments
You can also mix positional and keyword arguments:
introduce("Shefali", age=27)The rule is simple: Positional arguments must come before keyword arguments.
The Number of Arguments Matters
If a function expects two arguments:
def greet(name, city):
print("Hello", name)
print("You are from", city)you need to provide both: greet("Shefali", "Delhi")
If you provide only one: greet("Shefali")
Python raises a TypeError because the required argument is missing.
Similarly, providing too many arguments causes an error: greet("Shefali", "Delhi", "India")
The function only expects two arguments.
So, for now, remember: When using positional arguments, the number and order of the arguments should match the parameters in the function.
Parameters Can Be Different Data Types
Parameters aren’t limited to strings.
You can pass numbers too:
def add(a, b):
print(a + b)
add(5, 3)
# Output:
# 8You can also pass other values you’ve already learned about.
For example:
def show_age(age):
print("Your age is", age)
show_age(27)
# Output:
# Your age is 27The function simply receives the value and uses it.
Parameters Make Functions Reusable
This is one of the main reasons parameters are useful.
Without parameters, you might create separate functions:
def greet_shefali():
print("Hello Shefali")
def greet_john():
print("Hello John")That’s unnecessary.
Instead, we can create one function:
def greet(name):
print("Hello", name)Then reuse it:
greet("Shefali")
greet("John")
greet("Mark")
# Output:
# Hello Shefali
# Hello John
# Hello MarkOne function can now work with different values.
What Are Default Arguments?
A default argument is a value you give to a parameter when you define a function.
For example:
def greet(name="Mark"):
print("Hello", name)Here, "Mark" is the default value for the name parameter.
If we call the function without an argument:
greet()
# Output:
# Hello MarkPython uses the default value because we didn’t provide one.
Providing a Different Value
You can still provide your own value when calling the function.
def greet(name="Mark"):
print("Hello", name)
greet("John")
# Output:
# Hello JohnWhen you provide an argument, Python uses that value instead of the default.
So greet() uses Mark while greet("John")uses John.
Why Use Default Arguments?
Default arguments are useful when a parameter usually has a common value, but you still want to give the caller the option to change it.
For example:
def greet(name="there"):
print("Hello", name)Now both of these work:
greet()
greet("Shefali")
# Output:
# Hello there
# Hello ShefaliYou don’t have to provide a value every time.
Multiple Default Arguments
A function can have more than one parameter with a default value.
For example:
def greet(name="there", message="Hello"):
print(message, name)Now:
greet()
# Output:
# Hello thereYou can also provide different values:
greet("Shefali", "Welcome")
# Output:
# Welcome ShefaliYou can also provide only the first value:
greet("John")
# Output:
# Hello JohnHere, "John" replaces the default value for name, while "Hello" remains the default value for message.
Default Arguments and Positional Arguments
Default arguments become especially useful when a function has some parameters that are optional.
For example:
def introduce(name, city="Delhi"):
print("Name:", name)
print("City:", city)The name parameter doesn’t have a default value, so we need to provide it.
But city has a default value.
This works:
introduce("Shefali")
# Output:
# Name: Shefali
# City: DelhiAnd we can also provide a different city:
introduce("Shefali", "Jaipur")
# Output:
# Name: Shefali
# City: JaipurA Rule to Remember
When defining a function, parameters without default values should come before parameters with default values.
This works:
def greet(name, message="Hello"):
print(message, name)But this does not:
def greet(name="Shefali", message):
print(message, name)Python raises a SyntaxError because a parameter without a default value comes after a parameter with a default value.
For now, the simple rule to remember is: Required parameters first, default parameters after them.
Default Values Can Be Different Types
A default value doesn’t have to be a string.
It can be a number too:
def show_age(age=18):
print("Age:", age)
show_age()
show_age(27)
# Output:
# Age: 18
# Age: 27You can also use other values you’ve already learned about.
Default Arguments vs Required Arguments
Compare these two functions:
def greet(name):
print("Hello", name)Here, name is required.
You need to provide it: greet("Shefali")
Now compare:
def greet(name="there"):
print("Hello", name)Here, name has a default value.
You can call the function without providing it: greet()
The main difference is whether the parameter already has a value to use when no argument is provided.
Now, we saw above that a function without a return statement gives back None.
So, let’s learn how to make a function return a value.
What Does return Do?
The return statement sends a value back from a function.
For example:
def add(a, b):
return a + bWhen we call the function:
result = add(5, 3)
print(result)
# Output:
# 8The function calculates 5 + 3 and returns the result.
That returned value is then stored in result.
You can think of it like this:
Function → does some work → returns a value.return vs print()
This is an important difference.
Consider this function:
def add(a, b):
print(a + b)If we call it:
result = add(5, 3)It prints 8.
But result contains None.
Why?
Because print() displays a value. It doesn’t return that value from the function.
Now compare it with:
def add(a, b):
return a + bWhen we do:
result = add(5, 3)result contains 8.
So: print() displays a value.
return gives a value back from a function.
Using the Returned Value
One of the useful things about return is that you can store the returned value and use it later.
def add(a, b):
return a + b
result = add(5, 3)
print(result)
print(result * 2)
# Output:
# 8
# 16The function returns 8. We store it in result and then we can use result just like any other value.
Returning Different Values
A function can return different values depending on a condition.
For example:
def check_age(age):
if age >= 18:
return "Adult"
else:
return "Minor"Now:
result = check_age(20)
print(result)
# Output:
# AdultAnd:
result = check_age(15)
print(result)
# Output:
# MinorThe function returns a different value depending on the condition.
Returning Multiple Values
A function can also return more than one value at once.
For example:
def get_name_and_age():
return "Shefali", 27
name, age = get_name_and_age()
print(name)
print(age)
# Output:
# Shefali
# 27Here, the function returns two values: return "Shefali", 27
Python allows us to assign those values directly to two variables: name, age = get_name_and_age()
This is similar to the multiple variable assignment we saw in the variable lesson.
Python actually groups the returned values together as a tuple. We’ll learn more about tuples later.
For now, just remember that you can return multiple values and assign them to separate variables.
return Stops the Function
When Python reaches a return statement, the function immediately stops running.
For example:
def greet():
print("Hello")
return
print("This won't run")
greet()
# Output:
# HelloThe second print() never runs because return ended the function.
You can also return a value:
def greet():
print("Hello")
return "Done"
print("This won't run")Once Python reaches return "Done", the function stops.
Code placed after a return statement is called unreachable code.
Python won’t raise an error for it, but most code editors will warn you about it because that code can never run.
Returning More Complex Values
A function doesn’t have to return just numbers.
It can return strings and other values you’ve already learned about.
For example:
def get_name():
return "Shefali"
name = get_name()
print(name)
# Output:
# ShefaliYou can also return a result from a calculation:
def square(number):
return number * number
result = square(5)
print(result)
# Output:
# 25Returning Early
You can also use return to stop a function early.
For example:
def check_number(number):
if number < 0:
return "Negative number"
return "Positive number"If we call:
print(check_number(-5))
# Output:
# Negative numberWhen number < 0 is True, the first return runs and the function ends.
The second return isn’t reached.
One Function Can Return a Value to Another Part of Your Program
This is where functions become really useful.
For example:
def calculate_total(price, quantity):
return price * quantity
total = calculate_total(100, 3)
print("Total:", total)
# Output:
# Total: 300The function handles the calculation and gives the result back to the rest of the program.
The function doesn’t need to know what you’ll do with the result.
You can print it, store it, or use it in another calculation.
So far, we’ve learned how to pass arguments to functions.
But what if you don’t know how many arguments you’ll need?
For example, what if you want a function that can accept any number of values?
That’s where *args comes in.
What is args?
*args allows a function to accept any number of positional arguments.
For example:
def add_numbers(*args):
print(args)
add_numbers(10, 20, 30)
# Output:
# (10, 20, 30)Notice that the values are displayed inside parentheses.
Python collects all the positional arguments into a tuple.
We’ll learn more about tuples later. For now, just remember: *args collects multiple positional arguments into one variable.
args Is a Tuple
As we just saw, *args collects the arguments into a tuple.
Remember from data types lesson, that tuples are immutable. That means you can read their values, but you can’t change them.
For example:
def change(*args):
args[0] = 99
change(1, 2, 3)This raises: TypeError: 'tuple' object does not support item assignment
Since *args is a tuple, you can read its values but not change them.
Why Do We Need args?
Normally, you need to define how many parameters a function accepts:
def add_numbers(a, b):
print(a + b)
add_numbers(10, 20)This function expects exactly two arguments.
If you try add_numbers(10, 20, 30), Python raises an error because the function only has two parameters.
With *args, you can accept as many positional arguments as you need:
def add_numbers(*args):
print(args)
add_numbers(10, 20, 30, 40, 50)
# Output:
# (10, 20, 30, 40, 50)args Is Just a Name
The name args is not special.
The * is what matters.
For example:
def add_numbers(*numbers):
print(numbers)
add_numbers(10, 20, 30)
# Output:
# (10, 20, 30)You could technically call it anything:
def add_numbers(*values):
print(values)But *args is the common convention, so you’ll see it often in Python code.
Looping Through args
Since the collected values can be worked with one by one, you can loop through them:
def show_numbers(*args):
for number in args:
print(number)
show_numbers(10, 20, 30)
# Output:
# 10
# 20
# 30You can also use len():
def count_numbers(*args):
print("You provided", len(args), "numbers.")
count_numbers(10, 20, 30, 40)
# Output:
# You provided 4 numbers.This uses things you’ve already learned:
- functions
- arguments
forloopslen()
Using args to Add Numbers
Now let’s make our earlier example more useful:
def add_numbers(*args):
total = 0
for number in args:
total = total + number
return total
result = add_numbers(10, 20, 30)
print(result)
# Output:
# 60The function can now accept any number of numbers:
print(add_numbers(5, 10))
print(add_numbers(5, 10, 15))
print(add_numbers(5, 10, 15, 20, 25))
# Output:
# 15
# 30
# 75That’s the main benefit of *args.
You don’t have to decide in advance how many positional arguments the function should accept.
A Quick Note About sum()
Python already has a built-in sum() function that adds a collection of numbers.
For example:
numbers = (10, 20, 30)
print(sum(numbers))
# Output:
# 60We wrote our own add_numbers() function above to understand how *args works.
In real code, if you simply need to add a collection of numbers, Python’s built-in sum() is usually the simpler choice.
args With Regular Parameters
You can also use regular parameters together with *args.
For example:
def greet(greeting, *names):
for name in names:
print(greeting, name)
greet("Hello", "Shefali", "John", "Mark")
# Output:
# Hello Shefali
# Hello John
# Hello MarkHere:
greetingreceives "Hello"*namescollects the remaining positional arguments
So names contains: ("Shefali", "John", "Mark")
One Important Rule
When you use a regular parameter before *args, the regular parameter gets its value first.
For example:
def show(first, *others):
print("First:", first)
print("Others:", others)
show(10, 20, 30, 40)
# Output:
# First: 10
# Others: (20, 30, 40)The first argument goes to first and the remaining positional arguments are collected by *others.
args Doesn’t Mean “Any Type”
*args controls how many positional arguments a function accepts.
It doesn’t mean all the arguments have to be the same type.
For example:
def show_values(*args):
print(args)
show_values(10, "Hello", 3.14)
# Output:
# (10, 'Hello', 3.14)You can pass different types of values.
args vs Normal Parameters
Here’s the difference:
Normal parameters
def add(a, b):
return a + bThe function expects two arguments.
With *args
def add(*args):
total = 0
for number in args:
total = total + number
return totalThe function can accept any number of positional arguments.
add(1, 2)
add(1, 2, 3)
add(1, 2, 3, 4, 5)What Happens If You Don’t Pass Anything?
You can call a *args function without providing any arguments:
def show_values(*args):
print(args)
show_values()
# Output:
# ()The function receives an empty tuple.
This can be useful when you want a function to accept zero or more values.
A Common Mistake
Don’t forget the *.
This:
def show_values(args):
print(args)is a normal parameter.
It expects one argument: show_values(10)
But this:
def show_values(*args):
print(args)can accept multiple positional arguments: show_values(10, 20, 30)
So the * changes how Python collects the arguments.
What is kwargs?
**kwargs allows a function to accept any number of keyword arguments.
For example:
def show_info(**kwargs):
print(kwargs)
show_info(name="Shefali", age=27, city="Delhi")
# Output:
# {'name': 'Shefali', 'age': 27, 'city': 'Delhi'}Python collects the keyword arguments into a dictionary.
We’ll learn more about dictionaries later. For now, remember: **kwargs collects multiple keyword arguments into one variable.
Why Do We Need kwargs?
Normally, you define the parameters a function expects:
def introduce(name, age):
print("Name:", name)
print("Age:", age)
introduce(name="Shefali", age=27)This works well when you know exactly which parameters you need.
But what if you want your function to accept additional named values?
That’s where **kwargs can help:
def introduce(**kwargs):
print(kwargs)
introduce(name="Shefali", age=27, city="Delhi")
# Output:
# {'name': 'Shefali', 'age': 27, 'city': 'Delhi'}The function can accept any number of keyword arguments.
kwargs Is Just a Name
Just like args, the name kwargs is not special.
The ** is what matters.
You could write:
def show_info(**details):
print(details)
show_info(name="Shefali", age=27)
# Output:
# {'name': 'Shefali', 'age': 27}But **kwargs is the common convention you’ll usually see in Python code.
args vs kwargs
This is the main difference:
| *args | **kwargs |
|---|---|
| Accepts positional arguments | Accepts keyword arguments |
| Collected into a tuple | Collected into a dictionary |
| Uses one * | Uses two ** |
For example:
def show(*args, **kwargs):
print(args)
print(kwargs)
show(10, 20, name="Shefali", age=27)
# Output:
# (10, 20)
# {'name': 'Shefali', 'age': 27}The positional arguments go into args.
The keyword arguments go into kwargs.
Looping Through kwargs
Since kwargs is a dictionary, you can loop through it:
def show_info(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
show_info(name="Shefali", age=27, city="Delhi")
# Output:
# name : Shefali
# age : 27
# city : DelhiDon’t worry too much about .items() yet. We’ll learn dictionaries properly later.
For now, the important idea is that kwargs contains named values.
Using kwargs With Regular Parameters
You can also use regular parameters together with **kwargs.
For example:
def greet(name, **details):
print("Hello", name)
print(details)
greet("Shefali", age=27, city="Delhi")
# Output:
# Hello Shefali
# {'age': 27, 'city': 'Delhi'}Here:
namereceives "Shefali"**detailscollects the remaining keyword arguments
args and kwargs Together
You can use both in the same function.
def show_info(*args, **kwargs):
print("Positional:", args)
print("Keyword:", kwargs)
show_info("Python", "JavaScript", name="Shefali", age=27)
# Output:
# Positional: ('Python', 'JavaScript')
# Keyword: {'name': 'Shefali', 'age': 27}This gives the function a lot of flexibility.
You can pass:
- any number of positional arguments
- any number of keyword arguments
The Order Matters
When using regular parameters, *args, and **kwargs together, they follow a specific order.
For example:
def example(name, *args, **kwargs):
print(name)
print(args)
print(kwargs)
example(
"Shefali",
"Python",
"JavaScript",
age=27,
city="Delhi"
)
# Output:
# Shefali
# ('Python', 'JavaScript')
# {'age': 27, 'city': 'Delhi'}The general order is:
regular parameters → *args → **kwargsYou don’t need to memorize every rule around function parameters yet. Just remember this order when you see them together.
Keyword Arguments Need Names
With **kwargs, you pass values using names:
show_info(name="Shefali", age=27)This is different from *args:
show_info("Shefali", 27)The first version uses keyword arguments.
The second version uses positional arguments.
That’s why Python can separate them when both *args and **kwargs are used.
A Practical Example
Imagine you’re creating a function to display information about a user.
You don’t know which pieces of information the caller wants to provide.
You could use:
def user_profile(**details):
for key, value in details.items():
print(key, ":", value)
user_profile(
name="Shefali",
age=27,
city="Delhi"
)
# Output:
# name : Shefali
# age : 27
# city : DelhiAnother user could provide different information:
user_profile(
name="John",
country="India"
)The same function can handle both.
That’s one reason **kwargs is useful.
A Common Mistake
Don’t confuse *args and **kwargs.
This:
def show(*args):
print(args)expects positional arguments: show(10, 20, 30)
While this:
def show(**kwargs):
print(kwargs)
expects keyword arguments: show(name="Shefali", age=27)The number of * characters matters.
*args→ positional arguments**kwargs→ keyword arguments
What Happens If You Don’t Pass Anything?
Just like *args, you can call a **kwargs function without providing any arguments:
def show_info(**kwargs):
print(kwargs)
show_info()
# Output:
# {}You get an empty dictionary.
What Is pass?
Sometimes you want to create a function but don’t have any code to put inside it yet.
For example:
def add(a, b):This won’t work because Python expects an indented code block after the function definition.
You can use pass as a placeholder:
def add(a, b):
passThe function is now valid Python code, but it doesn’t do anything yet.
You can still call it:
def add(a, b):
pass
result = add(5, 3)
print(result)
# Output:
# NoneSince the function doesn’t return a value, it returns None, just like the functions we saw earlier.
When Would You Use pass?
pass is useful when you want to create the structure of your code now and fill in the implementation later.
For example:
def calculate_total():
pass
def display_result():
passYou can come back and write the actual code when you’re ready.
Think of pass as saying: “Do nothing here for now.”
What Is Recursion?
Now let’s look at a more interesting concept.
A recursive function is a function that calls itself.
For example:
def countdown(number):
if number == 0:
return
print(number)
countdown(number - 1)
countdown(5)
# Output:
# 5
# 4
# 3
# 2
# 1Let’s understand what happens.
The function starts with: countdown(5)
It prints 5, then calls itself with 4: countdown(4)
Then:
countdown(3)
countdown(2)
countdown(1)Eventually, it reaches: countdown(0)
At that point, this condition is true:
if number == 0:
returnThe function stops.
The Base Case
A recursive function needs a condition that tells it when to stop.
This is called the base case.
In our example:
if number == 0:
returnis the base case.
Without it, the function would keep calling itself.
For example, this is dangerous:
def countdown(number):
print(number)
countdown(number - 1)There is nothing telling the function to stop.
Eventually, Python will raise a: RecursionError
So remember: A recursive function needs a base case to stop the recursion.
A Practical Example: Factorial
Recursion can also be used to solve mathematical problems.
One common example is factorial.
The factorial of 5 is: 5 × 4 × 3 × 2 × 1 = 120
We can write a recursive function for this:
def factorial(number):
if number == 0:
return 1
return number * factorial(number - 1)
print(factorial(5))
# Output:
# 120Let’s see how this works:
factorial(5)
5 × factorial(4)
5 × 4 × factorial(3)
5 × 4 × 3 × factorial(2)
5 × 4 × 3 × 2 × factorial(1)
5 × 4 × 3 × 2 × 1The final result is: 120
The important part is this: return number * factorial(number - 1)
The function calls itself with a smaller number each time.
Eventually factorial(0) is reached.
That’s our base case:
if number == 0:
return 1Recursion and return
Notice that recursion often works together with return.
In our factorial example:
return number * factorial(number - 1)The function keeps calling itself until it reaches the base case.
Then the returned values are used to calculate the final result.
This is another example of why the return statement is so important.
Recursion vs Loops
You might notice that our countdown example could also be written using a loop:
number = 5
while number > 0:
print(number)
number = number - 1So why use recursion?
Recursion can be useful when a problem naturally breaks down into smaller versions of the same problem.
You’ll see recursion used in areas like:
- Working with trees
- Searching through nested structures
- Sorting algorithms
- Some mathematical problems
But recursion isn’t always the best choice. Many problems can be solved more simply with a loop.
For now, the important thing is understanding how recursion works.
Python’s Recursion Limit
Python limits how deeply a function can call itself. By default, this is usually around 1,000 recursive calls.
Python also doesn’t optimize recursive calls in the way some other languages do.
That’s why, in Python, loops are often a better choice for simple repetition.
Recursion is more useful when a problem naturally breaks down into smaller versions of itself, like working with nested structures or certain algorithms.
A Common Mistake
The most common mistake with recursion is forgetting the base case.
This function never stops:
def count(number):
print(number)
count(number + 1)There is no condition telling it when to stop.
A recursive function should always have a clear stopping condition.
👉 Next tutorial: Python Modules