Reputation: 618
Basically, I need to get few permutations of a list. So, the method that I have used is to shuffle the list string randomly to get the permutation and add it to a list, while adding I check if there exists the same permutation in the list. I am not able to implement the check. Here is the code that I have written.
list = [x for x in range(0,max)]
totalperm = 10
perms = []
while(len(perms) <> totalperm):
random.shuffle(list)
if list not in perms:
perms.append(list)
Please let me know what am I missing here.
Upvotes: 3
Views: 362
Reputation: 184191
This doesn't work because you're working with a reference to the single list the whole time, so it is always in the list after the first time you append it.
Consider:
perms = []
items = [1, 2, 3]
random.shuffle(mylist) # perhaps items is now [2, 1, 3]
perms.append(items) # perms is now [[2, 1, 3]]
random.shuffle(mylist) # perhaps items is now [1, 3, 2]
perms.append(items) # now what is perms?
The answer is, perms
has two references to a single list, so it is [1, 3, 2], [1, 3, 2]].
In your code, items
and perms[0]
are the same object and have the same value. So when you ask if items
is in perms
the answer is always yes. Because you just put it in there!
The solution is simple: add a copy of the list.
perms.append(items[:])
By the way, you should probably use a set
rather than a list
for storing your permutations. It's much faster to check membership of a set
and attempts to add duplicates are simply ignored. The only downside is that you can't put lists in a set
because lists are mutable and therefore unhashable -- fortunately, you can just convert them to tuples, which are immutable and hashable. Then you have:
items = range(0, max) # Python 3: items = list(range(0, max))
perms = set()
nump = 10
while len(perms) < nump:
random.shuffle(items)
perms.add(tuple(items))
Upvotes: 2
Reputation: 11915
Your code is going into an infinite loop because you change list
in place. Then you test to see if it is in perms
, big surprise, it is! So it can never append perms
.
Repeat ad nauseum.
Here's how I did it:
import random
max = 4
list = [x for x in range(0, max)]
totalperm = 10
perms = []
while(len(perms) < totalperm):
copiedlist = list[:]
random.shuffle(copiedlist)
if copiedlist not in perms:
perms.append(copiedlist)
print perms
else:
print "It's already there, egads!"
Upvotes: 0
Reputation: 16327
Use python's builtin set
to prevent duplicates:
perms = set()
while len(perms) != totalperm:
random.shuffle(lst)
perms.add(tuple(lst))
Upvotes: 4
Reputation: 17128
[1,2,3] in [[1,2,3], [4,5,6]] == True
Works for me. Is this all of your code?
Upvotes: 1
Reputation: 8066
When you're shuffling the list, you're modifying it in place. Later, you add a reference to it to your list of perms. Next time through your loop, you shuffle the list in place again. If you look at perms, it will contain n references to your original list.
You probably want to do something like this instead:
shuffled = list[:]
random.shuffle(shuffled)
if shuffled not in perms:
perms.append(shuffled)
Upvotes: 3