Python String Permutations (No itertools)
The quick way: using itertools
Python’s itertools.permutations handles this in one line:
from itertools import permutations
perms = sorted([''.join(p) for p in set(permutations('hello'))])
print(perms)
print(len(perms)) # 60
This gives all 60 unique permutations of “hello”, sorted alphabetically.
But many coding challenges explicitly say do not use built-in functions. If you need a solution without itertools, read on.
Without built-in functions: recursive approach
This builds permutations from scratch using only recursion and basic string operations:
def permutations(string):
if len(string) == 1:
return [string]
result = []
for i, char in enumerate(string):
remaining = string[:i] + string[i+1:]
for perm in permutations(remaining):
result.append(char + perm)
return sorted(set(result))
How it works:
- Base case: a single character has only one permutation — itself.
- For each character in the string, remove it and recursively find all permutations of what’s left.
- Prepend the removed character to each sub-permutation.
- Use
set()to eliminate duplicates (important for strings with repeated characters like “hello”). - Sort the result alphabetically.
perms = permutations('hello')
print(len(perms)) # 60
print(perms[:5]) # ['ehllo', 'ehlol', 'eholl', 'elhlo', 'ellho']
Returning results in alphabetical order
Both approaches above return results sorted alphabetically. If your challenge requires alphabetical output:
- With itertools: wrap in
sorted() - Without itertools: the
sorted(set(result))at the end handles it
If you need to avoid sorted() too, insert each permutation into the result list in order, or sort manually:
def permutations_alphabetical(string):
chars = sorted(string) # start with sorted characters
result = []
def backtrack(path, remaining):
if not remaining:
result.append(path)
return
seen = set()
for i, char in enumerate(remaining):
if char in seen:
continue
seen.add(char)
backtrack(path + char, remaining[:i] + remaining[i+1:])
backtrack('', ''.join(chars))
return result
This backtracking approach generates permutations in alphabetical order directly, without needing to sort afterward. It also skips duplicate characters at each recursion level, making it efficient for strings with repeated letters.
Complexity
- Time: O(n! × n) — there are n! permutations, each of length n.
- Space: O(n! × n) to store all results.
For a 10-character string with all unique characters, that’s 3,628,800 permutations. Keep input strings short.
Test cases
assert sorted(permutations('a')) == ['a']
assert sorted(permutations('ab')) == ['ab', 'ba']
assert len(permutations('abc')) == 6
assert len(permutations('hello')) == 60
assert permutations('aab') == ['aab', 'aba', 'baa']
Related challenges
If you enjoyed this, try these similar Python and Java coding puzzles:
- Find the number with the most digits in a list — another list-processing challenge that tests your ability to work with numbers without built-in shortcuts.
- Longest substring in alphabetical order — a string traversal problem where you track sequences of characters.