patternpythonMinor
Print permutations in an iterative way
Viewed 0 times
printwayiterativepermutations
Problem
I've written the following code to print all the permutations of a list. For example:
\$[1, 2, 3]\$ has these permutations: \$[1,2,3]\$, \$[1,3,2]\$, \$[2,1,3]\$, \$[2,3,1]\$, \$[3,1,2]\$, and \$[3,2,1]\$.
\$[1, 2, 3]\$ has these permutations: \$[1,2,3]\$, \$[1,3,2]\$, \$[2,1,3]\$, \$[2,3,1]\$, \$[3,1,2]\$, and \$[3,2,1]\$.
def insert_each_position(self, nums, insert_one):
res, len_of_nums = [], len(nums)
for idx in range(len_of_nums+1):
tmp = nums[:]
tmp.insert(idx, insert_one)
res.append(tmp)
return res
def permute(self, nums):
res, len_of_nums = [[]], len(nums)
for idx in range(len_of_nums):
cur_num = nums[idx]
tmp = []
for sub in res:
tmp.extend(self.insert_each_position(sub, cur_num))
res = tmp
return resSolution
As suggested by @netme in the comments, unless you need to write the permutation code yourself, it would be much better to use
That code is more compact, memory-efficient and faster than yours. The itertools module has been deliberately honed to be fast (I think it’s written in C rather than pure Python) and is worth looking into if you haven’t used it before – it’s really useful.
Assuming that you're supposed to be writing your own permutation, here are some comments on that code.
(Given the
-
Unless tuple unpacking makes the code cleaner or the variables are related, I'm generally inclined to split variable definitions over multiple lines. So I’d split the variable declarations over two lines in the start of each function.
I would then get rid of the
-
You don’t mention whether you’re using Python 2 or 3. If you’re using 2, you should use
-
There are no comments or docstrings. I had to guess how the function worked. You should explain what the code is trying to achieve, and why you wrote it that way – it will make it easer for me to review, and other people to use.
I would also suggest trying to pick better variable names.
-
My concern with your approach is that you gradually build up a list of all the permutations, which is going to be very memory inefficient and slow. Your program began to struggle when I asked it to permute
If you want something fast and you can’t use itertools, I suggest you consider looking at generators for yielding individual permutations. That’s a lot more memory efficient, and will be much faster.
itertools.permutations, as so:import itertools
for perm in itertools.permutations([1, 2, 3]):
print(perm)That code is more compact, memory-efficient and faster than yours. The itertools module has been deliberately honed to be fast (I think it’s written in C rather than pure Python) and is worth looking into if you haven’t used it before – it’s really useful.
Assuming that you're supposed to be writing your own permutation, here are some comments on that code.
(Given the
self parameter and the self.insert_each_position in the second function, I’m assuming these are class methods. I put them in their own class for testing.)-
Unless tuple unpacking makes the code cleaner or the variables are related, I'm generally inclined to split variable definitions over multiple lines. So I’d split the variable declarations over two lines in the start of each function.
I would then get rid of the
len_of_nums variable. It’s much clearer just to use len(nums) directly in the two places where this variable is used.-
You don’t mention whether you’re using Python 2 or 3. If you’re using 2, you should use
xrange() instead of range(), which is slightly faster and more memory efficient.-
There are no comments or docstrings. I had to guess how the function worked. You should explain what the code is trying to achieve, and why you wrote it that way – it will make it easer for me to review, and other people to use.
I would also suggest trying to pick better variable names.
res and tmp are not particularly descriptive or useful.-
My concern with your approach is that you gradually build up a list of all the permutations, which is going to be very memory inefficient and slow. Your program began to struggle when I asked it to permute
range(10). It think it has exponential growth, but I’m not sure.If you want something fast and you can’t use itertools, I suggest you consider looking at generators for yielding individual permutations. That’s a lot more memory efficient, and will be much faster.
Code Snippets
import itertools
for perm in itertools.permutations([1, 2, 3]):
print(perm)Context
StackExchange Code Review Q#97274, answer score: 5
Revisions (0)
No revisions yet.