Using recursion to find all permutations of a list in Python
Question:
So I am aware this topic has been covered. However, I am having troubles with my own implementation of it.
def permutation(word, fixed = [], passed = ""):
if passed != "":
fixed.append(passed)
if len(word) == 1:
fixed.append(word[0])
print fixed
else:
for i in range(len(word)):
passed = word[i]
rem = word[:i] + word[i+1:]
permutation(rem, fixed, passed)
permutation(["a","b","c"])
raw_input()
I am trying not to have return values but instead get to the base and then print the result. Although when I do this I get the following:
['a', 'b', 'c']
['a', 'b', 'c', 'c', 'b']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a', 'c', 'a', 'b']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a', 'c', 'a', 'b', 'b', 'a']
This seems to be close, however, I can tell that fixed is collecting all of the outputs and I don’t fully understand why.
When using recursion are each set of variables local to that call of the function? It is my understanding that is the case but it doesn’t really seem to be here.
This is not homework btw.
Updated code for anybody interested:
def permutation(word, fixed = "", passed = ""):
if passed != "":
fixed += passed
if len(word) == 1:
fixed += word[0]
print fixed
else:
for i in range(len(word)):
passed = word[i]
rem = word[:i] + word[i+1:]
permutation(rem, fixed, passed)
permutation(["a","b","c"])
raw_input()
Which produces the output:
abc
acb
bac
bca
cab
cba
Answers:
Your function is passed a reference to the list fixed
, so your function can mutate it. The accepted answer to this question has a great explanation.
Use this code
def get_permutations(sequence):
ls = []
if len(sequence) <= 1:
ls.append(sequence)
else:
ls = merge(sequence[0], get_permutations(sequence[1:]))
return ls
def merge(ch, sequence):
lst = []
for i in sequence:
for j in range(len(i)+1):
lst.append(i[0:j] + ch + i[j:])
return lst
if name == ‘main‘:
input = 'abcd'
print(get_permutations(input))
So I am aware this topic has been covered. However, I am having troubles with my own implementation of it.
def permutation(word, fixed = [], passed = ""):
if passed != "":
fixed.append(passed)
if len(word) == 1:
fixed.append(word[0])
print fixed
else:
for i in range(len(word)):
passed = word[i]
rem = word[:i] + word[i+1:]
permutation(rem, fixed, passed)
permutation(["a","b","c"])
raw_input()
I am trying not to have return values but instead get to the base and then print the result. Although when I do this I get the following:
['a', 'b', 'c']
['a', 'b', 'c', 'c', 'b']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a', 'c', 'a', 'b']
['a', 'b', 'c', 'c', 'b', 'b', 'a', 'c', 'c', 'a', 'c', 'a', 'b', 'b', 'a']
This seems to be close, however, I can tell that fixed is collecting all of the outputs and I don’t fully understand why.
When using recursion are each set of variables local to that call of the function? It is my understanding that is the case but it doesn’t really seem to be here.
This is not homework btw.
Updated code for anybody interested:
def permutation(word, fixed = "", passed = ""):
if passed != "":
fixed += passed
if len(word) == 1:
fixed += word[0]
print fixed
else:
for i in range(len(word)):
passed = word[i]
rem = word[:i] + word[i+1:]
permutation(rem, fixed, passed)
permutation(["a","b","c"])
raw_input()
Which produces the output:
abc
acb
bac
bca
cab
cba
Your function is passed a reference to the list fixed
, so your function can mutate it. The accepted answer to this question has a great explanation.
Use this code
def get_permutations(sequence):
ls = []
if len(sequence) <= 1:
ls.append(sequence)
else:
ls = merge(sequence[0], get_permutations(sequence[1:]))
return ls
def merge(ch, sequence):
lst = []
for i in sequence:
for j in range(len(i)+1):
lst.append(i[0:j] + ch + i[j:])
return lst
if name == ‘main‘:
input = 'abcd'
print(get_permutations(input))