Question 2 of Homework 11 from Berkeley's CS6 1A says:
Implement
permutations
, a generator function that takes in alst
and outputs all permutations oflst
, each as a list (see doctest for an example). The order in which you generate permutations is irrelevant.
This is my solution:
def permutations(lst):
if not lst:
yield []
return
"*** YOUR CODE HERE ***"
if type(lst)==tuple:
t=lst
lst=[]
for elem in t:
lst+=[elem]
if type(lst)==str:
lst=list(lst)
for elem in lst:
if elem:
l_temp=[lst[0]]
lst=lst[1:]
lst.extend(l_temp)
temp=list(lst[1:])
r_list=[]
lst_of_lst=[]
r_list+=[lst[0]]
while len(lst_of_lst)!=len(lst)-1:
holder=temp[1:]
t_holder=[temp[0]]
temp=[]
temp.extend(holder)
temp.extend(t_holder)
if len(r_list)==1:
r_list.extend([e for e in temp])
lst_of_lst+=[r_list,]
r_list=[]
r_list+=[lst[0]]
yield lst_of_lst
Test cases:
>>> sorted(permutations([1, 2, 3]))
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
>>> type(permutations([1, 2, 3]))
<class 'generator'>
>>> sorted(permutations((10, 20, 30)))
[[10, 20, 30], [10, 30, 20], [20, 10, 30], [20, 30, 10], [30, 10, 20], [30, 20, 10]]
>>> sorted(permutations("ab"))
[['a', 'b'], ['b', 'a']]
I need some suggestions in order to improve my code.
1 Answer 1
if type(lst)==tuple: t=lst lst=[] for elem in t: lst+=[elem] if type(lst)==str: lst=list(lst)
It's worth knowing that list
works on tuples too. (Online demo).
for elem in lst: if elem:
What purpose does this if
serve? It seems to me to introduce a bug, because the spec does not ask for falsy elements of lst
to be ignored.
l_temp=[lst[0]] lst=lst[1:]
[lst[0]]
would be more Pythonic as lst[:1]
. Spot the symmetry with the second line.
The reuse of names is not particularly helpful, especially given that lst
is a bad name. How about this?
first, rest = lst[:1], lst[1:]
lst.extend(l_temp)
Wait, that was just to rotate the list? Why? At this point I'm seriously in need of some comments to explain what you're trying to do.
temp=list(lst[1:]) r_list=[] lst_of_lst=[] r_list+=[lst[0]]
lst_of_lst
? That sounds like a bad name for a 2D array, but the spec doesn't ask for a 2D array and I can't see why you'd need one.
r_list
is again just lst[:1]
.
holder=temp[1:] t_holder=[temp[0]] temp=[] temp.extend(holder) temp.extend(t_holder)
Or in other words temp = temp[1:] + temp[:1]
. You're rotating lists often enough that maybe it's worth factoring out a function to make the flow of logic clearer.
if len(r_list)==1: r_list.extend([e for e in temp]) lst_of_lst+=[r_list,] r_list=[] r_list+=[lst[0]] yield lst_of_lst
There is no way this algorithm can be correct. Have you tested your code?
print len(list(permutations([1, 2, 3])))
print len(list(permutations([0, 1, 2, 3])))
should output
6
24
Once your code works, given that it's Python you should run it through an automated PEP8 checker. It should be easy to find one online.
-
\$\begingroup\$ Thanks for all the suggestions, I would improve upon all of my mistakes. \$\endgroup\$user7724050– user77240502017年07月20日 15:10:28 +00:00Commented Jul 20, 2017 at 15:10
-
1\$\begingroup\$ what I was trying to accomplish is as follows: for permutations of the list [1,2,3] for instance. In order to generate all possible combinations, I tried to fix one of the elements of the list let's say 1, so all of the possible combinations can be obtained by rotating the rest of the elements of the list so [1,2,3] would be first, [1,3,2]. And repeating the same procedure for the rest of the elements of the list. \$\endgroup\$user7724050– user77240502017年07月20日 15:19:58 +00:00Commented Jul 20, 2017 at 15:19
Explore related questions
See similar questions with these tags.
itertools.permutations
? Is this an exercise for a programming class? \$\endgroup\$