Python Program to Find All Substrings of a String
for i in range(len(s)) and for j in range(i+1, len(s)+1) then extract substrings with s[i:j].Examples
How to Think About It
Algorithm
Code
def all_substrings(s): result = [] for i in range(len(s)): for j in range(i + 1, len(s) + 1): result.append(s[i:j]) return result string = "abc" print(all_substrings(string))
Dry Run
Let's trace the string 'abc' through the code to find all substrings.
Initialize
Input string s = 'abc', result = []
Outer loop i=0
Inner loop j from 1 to 3: substrings s[0:1]='a', s[0:2]='ab', s[0:3]='abc' added
Outer loop i=1
Inner loop j from 2 to 3: substrings s[1:2]='b', s[1:3]='bc' added
Outer loop i=2
Inner loop j=3: substring s[2:3]='c' added
Return result
result = ['a', 'ab', 'abc', 'b', 'bc', 'c']
| i | j | Substring s[i:j] | Result List |
|---|---|---|---|
| 0 | 1 | a | ['a'] |
| 0 | 2 | ab | ['a', 'ab'] |
| 0 | 3 | abc | ['a', 'ab', 'abc'] |
| 1 | 2 | b | ['a', 'ab', 'abc', 'b'] |
| 1 | 3 | bc | ['a', 'ab', 'abc', 'b', 'bc'] |
| 2 | 3 | c | ['a', 'ab', 'abc', 'b', 'bc', 'c'] |
Why This Works
Step 1: Outer loop selects start index
The outer loop picks each position in the string as the start of a substring using i.
Step 2: Inner loop selects end index
The inner loop picks every possible end index after the start to form substrings with s[i:j].
Step 3: Collect substrings
Each substring slice is added to the result list, ensuring all continuous parts are included.
Alternative Approaches
def all_substrings(s): return [s[i:j] for i in range(len(s)) for j in range(i+1, len(s)+1)] print(all_substrings('abc'))
def all_substrings(s): if not s: return [] return [s[:i] for i in range(1, len(s)+1)] + all_substrings(s[1:]) print(all_substrings('abc'))
Complexity: O(n^2) time, O(n^2) space
Time Complexity
The nested loops each run up to n times, so total operations are proportional to n squared.
Space Complexity
Storing all substrings requires space proportional to the number of substrings, which is about n squared.
Which Approach is Fastest?
The list comprehension and nested loops have similar performance; recursion is slower and uses more call stack.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Nested loops | O(n^2) | O(n^2) | Clear and easy to understand |
| List comprehension | O(n^2) | O(n^2) | Concise and Pythonic |
| Recursion | O(n^2) | O(n^2) | Elegant but less efficient |