I came up with the following function:
def permutations(elements, arr, index):
if len(elements) == index:
print arr
for i in xrange(index, len(elements)):
arr[index] = elements[i]
permutations(elements, arr, index+1)
permutations([1,2,3], [0,0,0], 0)
However, it's printing:
[1, 2, 3]
[1, 3, 3]
[2, 2, 3]
[2, 3, 3]
[3, 2, 3]
[3, 3, 3]
what's wrong with my recursion?
Ok, I found this as a Java String recursive permutation algorithm that I translated to Python. I think it's the best solution:
def permutation(aux, ls):
if len(ls) == 0:
print(aux)
else:
for i in range(len(ls)):
permutation(aux + [ls[i]], ls[0:i] + ls[i+1:len(ls)])
permutation([], [1, 2, 3])
This is the output:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
The main problem in your code is that on i-th
position only possible values are from (i, n - 1)
where is n length of list. Thats why on last index in list you have all 3's. So the solution would be to iterate on all "levels" ( i-th
permutation call) from (0, n - 1)
. But because you will iterate from (0, n - 1)
on all "levels" you must introduce dictionary(used as hashset) where you will keep if some value ( j-th
element) is already chosen on previous calls. Easiest solution would be something like:
def perm(elements):
def inner(arr, index, visited):
if len(elements) == index:
print arr
for i in xrange(0, len(elements)):
if (i not in visited):
visited[i] = 1; # mark so same index can not be used later
arr[index] = elements[i]
inner(arr, index + 1, visited);
del visited[i] # free index
inner([0] * len(elements), 0, {});
perm([1,2,3])
As @Hooked already mentioned it would be best if you can use permutations function from itertools module . Note that on Python 3, you can put arr and visited outside of function parameters with nonlocal
. Also, here you are one more solution, without dictionary, but with additional list which will hold all possible values for i-th
level (position) of permutation. In this solution, however order of permutations is not preserved
def perm(elements):
def inner(arr, index, possible):
if len(elements) == index:
print arr
lenForLevel = len(elements) - index;
for i in xrange(0, lenForLevel):
arr[index] = possible[i]
(possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
inner(arr, index + 1, possible);
(possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
inner([0] * len(elements), 0, list(elements))
perm([1,2,3,4])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.