Whenever you face a problem like this, try to express the result of the function with the same function.

In your case, you can get the result by adding the first number with the result of calling the same function with rest of the elements in the list.

For example,

listSum([1, 3, 4, 5, 6]) = 1 + listSum([3, 4, 5, 6])
                         = 1 + (3 + listSum([4, 5, 6]))
                         = 1 + (3 + (4 + listSum([5, 6])))
                         = 1 + (3 + (4 + (5 + listSum([6]))))
                         = 1 + (3 + (4 + (5 + (6 + listSum([])))))

Now, what should be the result of listSum([])? It should be 0. That is called base condition of your recursion. When the base condition is met, the recursion will come to an end. Now, lets try to implement it.

The main thing here is, splitting the list. You can use slicing to do that.

Simple version

>>> def listSum(ls):
...     # Base condition
...     if not ls:
...         return 0
...
...     # First element + result of calling `listsum` with rest of the elements
...     return ls[0] + listSum(ls[1:])
>>> 
>>> listSum([1, 3, 4, 5, 6])
19

Tail Call Recursion

Once you understand how the above recursion works, you can try to make it a little bit better. Now, to find the actual result, we are depending on the value of the previous function also. The return statement cannot immediately return the value till the recursive call returns a result. We can avoid this by, passing the current to the function parameter, like this

>>> def listSum(ls, result):
...     if not ls:
...         return result
...     return listSum(ls[1:], result + ls[0])
... 
>>> listSum([1, 3, 4, 5, 6], 0)
19

Here, we pass what the initial value of the sum to be in the parameters, which is zero in listSum([1, 3, 4, 5, 6], 0). Then, when the base condition is met, we are actually accumulating the sum in the result parameter, so we return it. Now, the last return statement has listSum(ls[1:], result + ls[0]), where we add the first element to the current result and pass it again to the recursive call.

This might be a good time to understand Tail Call. It would not be relevant to Python, as it doesn't do Tail call optimization.


Passing around index version

Now, you might think that we are creating so many intermediate lists. Can I avoid that?

Of course, you can. You just need the index of the item to be processed next. But now, the base condition will be different. Since we are going to be passing index, how will we determine how the entire list has been processed? Well, if the index equals to the length of the list, then we have processed all the elements in it.

>>> def listSum(ls, index, result):
...     # Base condition
...     if index == len(ls):
...         return result
...
...     # Call with next index and add the current element to result
...     return listSum(ls, index + 1, result + ls[index])
... 
>>> listSum([1, 3, 4, 5, 6], 0, 0)
19

Inner function version

If you look at the function definition now, you are passing three parameters to it. Lets say you are going to release this function as an API. Will it be convenient for the users to pass three values, when they actually find the sum of a list?

Nope. What can we do about it? We can create another function, which is local to the actual listSum function and we can pass all the implementation related parameters to it, like this

>>> def listSum(ls):
...
...     def recursion(index, result):
...         if index == len(ls):
...             return result
...         return recursion(index + 1, result + ls[index])
...
...     return recursion(0, 0)
... 
>>> listSum([1, 3, 4, 5, 6])
19

Now, when the listSum is called, it just returns the return value of recursion inner function, which accepts the index and the result parameters. Now we are only passing those values, not the users of listSum. They just have to pass the list to be processed.

In this case, if you observe the parameters, we are not passing ls to recursion but we are using it inside it. ls is accessible inside recursion because of the closure property.


Default parameters version

Now, if you want to keep it simple, without creating an inner function, you can make use of the default parameters, like this

>>> def listSum(ls, index=0, result=0):
...     # Base condition
...     if index == len(ls):
...         return result
...
...     # Call with next index and add the current element to result
...     return listSum(ls, index + 1, result + ls[index])
... 
>>> listSum([1, 3, 4, 5, 6])
19

Now, if the caller doesn't explicitly pass any value, then 0 will be assigned to both index and result.


Recursive Power problem

Now, lets apply the ideas to a different problem. For example, lets try to implement the power(base, exponent) function. It would return the value of base raised to the power exponent.

power(2, 5) = 32
power(5, 2) = 25
power(3, 4) = 81

Now, how can we do this recursively? Let us try to understand how those results are achieved.

power(2, 5) = 2 * 2 * 2 * 2 * 2 = 32
power(5, 2) = 5 * 5             = 25
power(3, 4) = 3 * 3 * 3 * 3     = 81

Hmmm, so we get the idea. The base multiplied to itself, exponent times gives the result. Okay, how do we approach it. Lets try to define the solution with the same function.

power(2, 5) = 2 * power(2, 4)
            = 2 * (2 * power(2, 3))
            = 2 * (2 * (2 * power(2, 2)))
            = 2 * (2 * (2 * (2 * power(2, 1))))

What should be the result if anything raised to power 1? Result will be the same number, right? We got our base condition for our recursion :-)

            = 2 * (2 * (2 * (2 * 2)))
            = 2 * (2 * (2 * 4))
            = 2 * (2 * 8)
            = 2 * 16
            = 32

Alright, lets implement it.

>>> def power(base, exponent):
...     # Base condition, if `exponent` is lesser than or equal to 1, return `base`
...     if exponent <= 1:
...         return base
...
...     return base * power(base, exponent - 1)
... 
>>> power(2, 5)
32
>>> power(5, 2)
25
>>> power(3, 4)
81

Okay, how will be define the Tail call optimized version of it? Lets pass the current result as the parameter to the function itself and return the result when the base condition it met. Let's keep it simple and use the default parameter approach directly.

>>> def power(base, exponent, result=1):
...     # Since we start with `1`, base condition would be exponent reaching 0
...     if exponent <= 0:
...         return result
...
...     return power(base, exponent - 1, result * base)
... 
>>> power(2, 5)
32
>>> power(5, 2)
25
>>> power(3, 4)
81

Now, we reduce the exponent value in every recursive call and multiple result with base and pass it to the recursive power call. We start with the value 1, because we are approaching the problem in reverse. The recursion will happen like this

power(2, 5, 1) = power(2, 4, 1 * 2)
               = power(2, 4, 2)
               = power(2, 3, 2 * 2)
               = power(2, 3, 4)
               = power(2, 2, 4 * 2)
               = power(2, 2, 8)
               = power(2, 1, 8 * 2)
               = power(2, 1, 16)
               = power(2, 0, 16 * 2)
               = power(2, 0, 32)

Since exponent becomes zero, the base condition is met and the result will be returned, so we get 32 :-)

Answer from thefourtheye on Stack Overflow
Top answer
1 of 5
115

Whenever you face a problem like this, try to express the result of the function with the same function.

In your case, you can get the result by adding the first number with the result of calling the same function with rest of the elements in the list.

For example,

listSum([1, 3, 4, 5, 6]) = 1 + listSum([3, 4, 5, 6])
                         = 1 + (3 + listSum([4, 5, 6]))
                         = 1 + (3 + (4 + listSum([5, 6])))
                         = 1 + (3 + (4 + (5 + listSum([6]))))
                         = 1 + (3 + (4 + (5 + (6 + listSum([])))))

Now, what should be the result of listSum([])? It should be 0. That is called base condition of your recursion. When the base condition is met, the recursion will come to an end. Now, lets try to implement it.

The main thing here is, splitting the list. You can use slicing to do that.

Simple version

>>> def listSum(ls):
...     # Base condition
...     if not ls:
...         return 0
...
...     # First element + result of calling `listsum` with rest of the elements
...     return ls[0] + listSum(ls[1:])
>>> 
>>> listSum([1, 3, 4, 5, 6])
19

Tail Call Recursion

Once you understand how the above recursion works, you can try to make it a little bit better. Now, to find the actual result, we are depending on the value of the previous function also. The return statement cannot immediately return the value till the recursive call returns a result. We can avoid this by, passing the current to the function parameter, like this

>>> def listSum(ls, result):
...     if not ls:
...         return result
...     return listSum(ls[1:], result + ls[0])
... 
>>> listSum([1, 3, 4, 5, 6], 0)
19

Here, we pass what the initial value of the sum to be in the parameters, which is zero in listSum([1, 3, 4, 5, 6], 0). Then, when the base condition is met, we are actually accumulating the sum in the result parameter, so we return it. Now, the last return statement has listSum(ls[1:], result + ls[0]), where we add the first element to the current result and pass it again to the recursive call.

This might be a good time to understand Tail Call. It would not be relevant to Python, as it doesn't do Tail call optimization.


Passing around index version

Now, you might think that we are creating so many intermediate lists. Can I avoid that?

Of course, you can. You just need the index of the item to be processed next. But now, the base condition will be different. Since we are going to be passing index, how will we determine how the entire list has been processed? Well, if the index equals to the length of the list, then we have processed all the elements in it.

>>> def listSum(ls, index, result):
...     # Base condition
...     if index == len(ls):
...         return result
...
...     # Call with next index and add the current element to result
...     return listSum(ls, index + 1, result + ls[index])
... 
>>> listSum([1, 3, 4, 5, 6], 0, 0)
19

Inner function version

If you look at the function definition now, you are passing three parameters to it. Lets say you are going to release this function as an API. Will it be convenient for the users to pass three values, when they actually find the sum of a list?

Nope. What can we do about it? We can create another function, which is local to the actual listSum function and we can pass all the implementation related parameters to it, like this

>>> def listSum(ls):
...
...     def recursion(index, result):
...         if index == len(ls):
...             return result
...         return recursion(index + 1, result + ls[index])
...
...     return recursion(0, 0)
... 
>>> listSum([1, 3, 4, 5, 6])
19

Now, when the listSum is called, it just returns the return value of recursion inner function, which accepts the index and the result parameters. Now we are only passing those values, not the users of listSum. They just have to pass the list to be processed.

In this case, if you observe the parameters, we are not passing ls to recursion but we are using it inside it. ls is accessible inside recursion because of the closure property.


Default parameters version

Now, if you want to keep it simple, without creating an inner function, you can make use of the default parameters, like this

>>> def listSum(ls, index=0, result=0):
...     # Base condition
...     if index == len(ls):
...         return result
...
...     # Call with next index and add the current element to result
...     return listSum(ls, index + 1, result + ls[index])
... 
>>> listSum([1, 3, 4, 5, 6])
19

Now, if the caller doesn't explicitly pass any value, then 0 will be assigned to both index and result.


Recursive Power problem

Now, lets apply the ideas to a different problem. For example, lets try to implement the power(base, exponent) function. It would return the value of base raised to the power exponent.

power(2, 5) = 32
power(5, 2) = 25
power(3, 4) = 81

Now, how can we do this recursively? Let us try to understand how those results are achieved.

power(2, 5) = 2 * 2 * 2 * 2 * 2 = 32
power(5, 2) = 5 * 5             = 25
power(3, 4) = 3 * 3 * 3 * 3     = 81

Hmmm, so we get the idea. The base multiplied to itself, exponent times gives the result. Okay, how do we approach it. Lets try to define the solution with the same function.

power(2, 5) = 2 * power(2, 4)
            = 2 * (2 * power(2, 3))
            = 2 * (2 * (2 * power(2, 2)))
            = 2 * (2 * (2 * (2 * power(2, 1))))

What should be the result if anything raised to power 1? Result will be the same number, right? We got our base condition for our recursion :-)

            = 2 * (2 * (2 * (2 * 2)))
            = 2 * (2 * (2 * 4))
            = 2 * (2 * 8)
            = 2 * 16
            = 32

Alright, lets implement it.

>>> def power(base, exponent):
...     # Base condition, if `exponent` is lesser than or equal to 1, return `base`
...     if exponent <= 1:
...         return base
...
...     return base * power(base, exponent - 1)
... 
>>> power(2, 5)
32
>>> power(5, 2)
25
>>> power(3, 4)
81

Okay, how will be define the Tail call optimized version of it? Lets pass the current result as the parameter to the function itself and return the result when the base condition it met. Let's keep it simple and use the default parameter approach directly.

>>> def power(base, exponent, result=1):
...     # Since we start with `1`, base condition would be exponent reaching 0
...     if exponent <= 0:
...         return result
...
...     return power(base, exponent - 1, result * base)
... 
>>> power(2, 5)
32
>>> power(5, 2)
25
>>> power(3, 4)
81

Now, we reduce the exponent value in every recursive call and multiple result with base and pass it to the recursive power call. We start with the value 1, because we are approaching the problem in reverse. The recursion will happen like this

power(2, 5, 1) = power(2, 4, 1 * 2)
               = power(2, 4, 2)
               = power(2, 3, 2 * 2)
               = power(2, 3, 4)
               = power(2, 2, 4 * 2)
               = power(2, 2, 8)
               = power(2, 1, 8 * 2)
               = power(2, 1, 16)
               = power(2, 0, 16 * 2)
               = power(2, 0, 32)

Since exponent becomes zero, the base condition is met and the result will be returned, so we get 32 :-)

2 of 5
3

Early exit is typical for recursive functions. seq is falsy when empty (therefore when there are no numbers left to sum).

Slice syntax allows to pass sequence to recursively called function without integer consumed in current step.

def listSum(seq):
    if not seq:
        return 0
    return seq[0] + listSum(seq[1:])

print listSum([1,3,4,5,6])  # prints 19
🌐
Codecademy
codecademy.com › learn › learn-recursion-python › modules › recursion-python › cheatsheet
Learn Recursion with Python: Recursion: Python Cheatsheet | Codecademy
Using another while loop, iterate through the call stack list. Pop the last item off the list and add it to a variable to store the accumulative result. Print the result. ... In Python, a recursive function accepts an argument and includes a condition to check whether it matches the base case.
Discussions

Lists and recursion
To all following commenters: please, do not bring up the old circlejerk jokes/memes about recursion ("Understanding recursion...", "This is recursion...", etc.). We've all heard them n+2 too many times. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns. More on reddit.com
🌐 r/learnprogramming
6
1
September 19, 2022
How to transform a flat list into a nested list using Recursion
The position won't help you since the list is unordered. The arguments need to be the list and the decade. def group_list(L, decade=10): if not L: return [[]] keep_list, remaining = [], [] #split the list into 2 lists, one for elements that are less than this decade, and the leftovers return [keep_list] + group_list(remaining, decade + 10)) More on reddit.com
🌐 r/learnpython
6
4
February 6, 2022
Recursive function for finding length of a list
def length(a_list): if not a_list: return 0 return 1 + a_list(some_list[1: ]) This function is doing very little. It's simply seeing if the list is empty, if it is, return 0. Otherwise, pass a slice of the list skipping the first value to this function and look again. Eventually it's going to reach the end of the list and return 0. When it does, it's going to return 1 + n for each nested call which will be equal to the number of elements in the list. More on reddit.com
🌐 r/learnpython
6
0
November 2, 2022
How to return a list of elements from a recursive function (Fibonacci sequence)?
The problem is that your current method wastes a LOT of power. For example: fibonacci(5) calls fibonacci(4) and fibonacci(3). fibonacci(4) in turn calls fibonacci(3) and fibonacci(2). See how you call fibonacci(3) two separate times? Times that by the entire tree. Therefore to do what you want from this you need to throw out all that extra data. def fibonacci(n): if n == 1 or n == 0: return [n] minus_one = fibonacci(n-1) minus_two = fibonacci(n-2) current = minus_one[0] + minus_two[0] # throw out everything in minus_two except the last number return [current] + minus_one More on reddit.com
🌐 r/learnpython
13
0
March 2, 2022
🌐
W3Schools
w3schools.com › python › python_recursion.asp
Python Recursion
Remove List Duplicates Reverse a String Add Two Numbers · Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Practice Problems Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Training ... Recursion is when a function calls itself.
🌐
GeeksforGeeks
geeksforgeeks.org › python › recursion-in-python
Recursion in Python - GeeksforGeeks
Recursive Case: multiplies n with the factorial of n-1 until it reaches the base case. Example 2: This code defines a recursive function to calculate nth Fibonacci number, where each number is the sum of the two preceding ones, starting from 0 and 1.
Published: May 19, 2026
🌐
Readthedocs
understanding-recursion.readthedocs.io › en › latest › 07 Lists of Lists.html
Summing a List of Lists — Understanding Recursion Using Python 1.0 documentation
To illustrate, here is another example, and one where recursion really begins to shine. Say we have a list L of integers, and we want to return the sum. However, some of these integers sit in sublists within L. We can’t use Python’s sum() method, since it requires that the list be ‘flat’ - we get a Type Error if we try to sum an integer with a list.
🌐
University of Toronto
cs.toronto.edu › ~david › course-notes › csc110-111 › 14-induction-and-recursion › 05-recursive-lists.html
14.5 Recursive Lists
Preconditions: - every element in this list is an int """ if self._first is None: # Base case: this list is empty return 0 else: # Recursive case: this list is non-empty return self._first + self._rest.sum() You might find this implementation both surprising and unsurprising at the same time. Unsurprising, because it is a natural translation of the recursive mathematical function, and so if you believe that function is correct, you should believe that this Python function is correct too.
🌐
Pythonspot
pythonspot.com › recursion
Python Recursion — Tutorial with Examples | Pythonspot
January 1, 2026 - Factorial with recursion The mathematical definition of factorial is: n! = n * (n-1)!, if n > 1 and f(1) = 1. Example: 3! = 3 x 2 x 1 = 6. We can implement this in Python using a recursive function:
Find elsewhere
🌐
Programiz
programiz.com › python-programming › recursion
Python Recursion (Recursive Function)
In Python, we know that a function can call other functions. It is even possible for the function to call itself. These types of construct are termed as recursive functions. The following image shows the working of a recursive function called recurse. Following is an example of a recursive function to find the factorial of an integer.
🌐
Real Python
realpython.com › python-recursion
Recursion in Python: An Introduction – Real Python
July 27, 2026 - Then, when you Quicksort the sublists recursively, you’d pass the slices of the list to the left and right of the pivot item. Alternately, you can use Python’s list manipulation capability to create new lists instead of operating on the original list in place.
🌐
DataCamp
datacamp.com › tutorial › recursion-in-python
Recursion in Python: Concepts, Examples, and Tips | DataCamp
April 9, 2025 - Understanding this stack behavior is crucial because it explains both the power and limitations of recursion in Python. It elegantly preserves context but can also lead to memory issues with deep recursion. The factorial function is a classic example used to demonstrate recursion.
🌐
Invent with Python
inventwithpython.com › blog › 22-examples-of-recursive-functions.html
22 Examples of Recursive Functions in Python - Invent with Python
October 4, 2021 - For example, the divide step takes a list, such as [0, 7, 6, 3, 1, 2, 5, 4], and splits it into two lists, like [0, 7, 6, 3] and [1, 2, 5, 4], to pass to two recursive function calls.
🌐
Datamentor
datamentor.io › python › recursive-function
Python Recursion (With Examples)
If num equals 1, it simply returns 1 since that's the base case. Otherwise, it returns num plus the result of a recursive call to calculate_sum(num - 1).
🌐
Reddit
reddit.com › r/learnprogramming › lists and recursion
r/learnprogramming on Reddit: Lists and recursion
September 19, 2022 -

Hi everyone, I’ve been studying python for one year now, but I still have not grasped recursion very well. I can understand the basic fibonacci example, and I understand how the call stack works, but one thing I can’t seem to figure out is how to use lists recursively. I’ve tried to look for some examples on stack overflow, but they were completely unreadable. The code just gets too complicated, and I can’t understand what the program is doing. Could anyone show me an easy example of appending elements to a list while using recursion? Also, are there are any resources that you’d recommend to master recursion? Thank you in advance

🌐
Real Python
realpython.com › python-thinking-recursively
Thinking Recursively in Python – Real Python
March 27, 2018 - A data structure is recursive if it can be defined in terms of a smaller version of itself. A list is an example of a recursive data structure. Let me demonstrate.
🌐
Tutorialspoint
tutorialspoint.com › python › python_recursion.htm
Python - Recursion
The base case provides a direct solution to the simplest instance of the problem ensuring that each recursive call gets closer to this terminating condition. The most popular example of recursion is calculation of factorial.
🌐
w3resource
w3resource.com › python-exercises › data-structures-and-algorithms › python-recursion.php
Python Data Structures and Algorithms: Recursion - Exercises, Practice, Solution - w3resource
July 28, 2025 - Write a Python program to calculate the sum of the positive integers of n+(n-2)+(n-4)... (until n-x =< 0) using recursion . Test Data: sum_series(6) -> 12 sum_series(10) -> 30 Click me to see the sample solution ... Write a Python program to calculate the sum of harmonic series upto n terms. Note: The harmonic sum is the sum of reciprocals of the positive integers. Example :
🌐
Codementor
codementor.io › community › python recursion by example
Python Recursion by Example | Codementor
March 18, 2019 - So this useless function is a basic example of recursion. Let's run through the changes to the stack just like before. We first execute the line marked with ### start. This gives us a stack like: The function then prints out the current spam iteration number and then calls foo again. Note that the initial foo call did not return so it remains on the stack. Now Python deals with the top frame and calls foo again.
🌐
Mimo
mimo.org › glossary › python › recursion
Python Recursion: Syntax, Usage, and Examples
Python recursion is a technique where a function calls itself to solve a problem in a step-by-step manner. It is commonly used for solving problems that can be broken down into smaller subproblems, such as calculating factorials, Fibonacci sequences, and performing binary search.
🌐
freeCodeCamp
freecodecamp.org › news › recursion-in-python-intro-for-beginners
Recursion in Python – A Practical Introduction for Beginners
March 12, 2026 - If you forget the base case, the function will keep calling itself forever — until Python raises a RecursionError. We'll talk more about that later. Let's start with the classic example: calculating a factorial.
🌐
Scaler
scaler.com › home › topics › python › recursion in python
Recursion in Python - Scaler Topics
April 7, 2024 - A linked list in Python is recursively defined as: An empty linked list. A node followed by a linked list smaller than the original linked list by one node. To insert a node at the end of a linked list, we need to traverse the linked list until the final element, i.e., the link of the element, is a null value (None). The following example shows recursive functions used for the insertion and traversal of the linked list.