AKG
AKG

Reputation: 618

Test to check if a list is present inside a python list of lists

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

Answers (5)

kindall
kindall

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

jgritty
jgritty

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

Rob Wouters
Rob Wouters

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

bluepnume
bluepnume

Reputation: 17128

[1,2,3] in [[1,2,3], [4,5,6]] == True

Works for me. Is this all of your code?

Upvotes: 1

Chris AtLee
Chris AtLee

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

Related Questions