Python Program to Reverse a List Using Recursion
def reverse_list(lst): return [] if not lst else reverse_list(lst[1:]) + [lst[0]] which calls itself with the rest of the list and adds the first element at the end.Examples
How to Think About It
Algorithm
Code
def reverse_list(lst): if not lst: return [] return reverse_list(lst[1:]) + [lst[0]] # Example usage print(reverse_list([1, 2, 3, 4]))
Dry Run
Let's trace reversing the list [1, 2, 3, 4] through the code
Initial call
Input list: [1, 2, 3, 4]. Not empty, so call reverse_list([2, 3, 4]) and plan to add 1 at the end.
Second call
Input list: [2, 3, 4]. Not empty, call reverse_list([3, 4]) and plan to add 2 at the end.
Third call
Input list: [3, 4]. Not empty, call reverse_list([4]) and plan to add 3 at the end.
Fourth call
Input list: [4]. Not empty, call reverse_list([]) and plan to add 4 at the end.
Base case
Input list: []. Empty list, return [].
Returning from fourth call
reverse_list([]) returned []. Add 4 at the end: [4].
Returning from third call
reverse_list([4]) returned [4]. Add 3 at the end: [4, 3].
Returning from second call
reverse_list([3, 4]) returned [4, 3]. Add 2 at the end: [4, 3, 2].
Returning from initial call
reverse_list([2, 3, 4]) returned [4, 3, 2]. Add 1 at the end: [4, 3, 2, 1].
| Call Level | Input List | Returned Value |
|---|---|---|
| 5 | [] | [] |
| 4 | [4] | [4] |
| 3 | [3, 4] | [4, 3] |
| 2 | [2, 3, 4] | [4, 3, 2] |
| 1 | [1, 2, 3, 4] | [4, 3, 2, 1] |
Why This Works
Step 1: Base case stops recursion
When the list is empty (if not lst), the function returns an empty list to stop further calls.
Step 2: Recursive call processes smaller list
The function calls itself with the list excluding the first element (lst[1:]), reducing the problem size.
Step 3: Combining results reverses list
After the recursive call returns the reversed smaller list, the first element is added at the end, building the reversed list step by step.
Alternative Approaches
def reverse_in_place(lst, start=0, end=None): if end is None: end = len(lst) - 1 if start >= end: return lst lst[start], lst[end] = lst[end], lst[start] return reverse_in_place(lst, start + 1, end - 1) print(reverse_in_place([1, 2, 3, 4]))
def reverse_slice(lst): return lst[::-1] print(reverse_slice([1, 2, 3, 4]))
Complexity: O(n^2) time, O(n^2) space
Time Complexity
Each recursive call creates a new list slice which takes O(n) time, and there are n calls, leading to O(n^2) time.
Space Complexity
Each call creates a new list slice and a new list when concatenating, so space grows roughly O(n^2).
Which Approach is Fastest?
The in-place recursion method is faster and uses less memory (O(n) time and O(n) space) compared to slicing recursion.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Recursive slicing | O(n^2) | O(n^2) | Learning recursion, simple code |
| In-place recursion | O(n) | O(n) | Memory efficient, modifies original list |
| Slicing (non-recursive) | O(n) | O(n) | Fastest, simplest, no recursion |