Generating permutations in Python 3
Question:
I wrote this simple permutations generator in Python 3. The permuted digits are a string, and the function should yield successive strings as well. The function returns nothing. Could I please ask for some help with this?
def permutations(digits):
if digits:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
print(list(permutations("12345")))
Answers:
The problem is subtle. The inner-most recursion does not yield anything, not even an empty string. Therefore its caller does not loop over any subpermutations. etc.
def permutations(digits):
if digits:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
else:
yield ""
Once the string of digits is down to a single character, remaining
becomes an empty string. Then the next recursion doesn’t yield anything. That means the next higher recursion level never executes its loop and so on and so forth.
The simplest fix would be this:
def permutations(digits):
for d in digits:
remaining = digits.replace(d,"")
if not remaining:
yield d
continue
for p in permutations(remaining):
yield d+p
Consider the base case of your function, where there is a single character. The permutations of 'a'
are ['a']
. Your code, however, returns an empty list because it never enters the inner for loop (it returns nothing if the length of the string is zero).
You can fix this by adding an if statement to explicitly handle the case where there is one character in the string.
def permutations(digits):
if len(digits) == 0:
return
elif len(digits) == 1:
yield digits
else:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
print(list(permutations("12345")))
I wrote this simple permutations generator in Python 3. The permuted digits are a string, and the function should yield successive strings as well. The function returns nothing. Could I please ask for some help with this?
def permutations(digits):
if digits:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
print(list(permutations("12345")))
The problem is subtle. The inner-most recursion does not yield anything, not even an empty string. Therefore its caller does not loop over any subpermutations. etc.
def permutations(digits):
if digits:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
else:
yield ""
Once the string of digits is down to a single character, remaining
becomes an empty string. Then the next recursion doesn’t yield anything. That means the next higher recursion level never executes its loop and so on and so forth.
The simplest fix would be this:
def permutations(digits):
for d in digits:
remaining = digits.replace(d,"")
if not remaining:
yield d
continue
for p in permutations(remaining):
yield d+p
Consider the base case of your function, where there is a single character. The permutations of 'a'
are ['a']
. Your code, however, returns an empty list because it never enters the inner for loop (it returns nothing if the length of the string is zero).
You can fix this by adding an if statement to explicitly handle the case where there is one character in the string.
def permutations(digits):
if len(digits) == 0:
return
elif len(digits) == 1:
yield digits
else:
for d in digits:
remaining = digits.replace(d,"")
for p in permutations(remaining):
yield d+p
print(list(permutations("12345")))