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")))
Asked By: ArekBulski

||

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 ""
Answered By: ArekBulski

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
Answered By: Homer512

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")))
Answered By: Miguel Guthridge
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.