简体   繁体   中英

Finite permutations of a list python

I have a list and would like to generate a finite number of permutation with no repeated elements.

itertools.permutations(x)

gives all possible orderings but I only need a specific number of permutation. (my initial list contains ~200 elements => 200! will take an unreasonable amount of time and I don't need all of them)

what I have done so far

def createList(My_List):
    New_List = random.sample(My_List, len(My_List))
    return New_List

def createManyList(Nb_of_Lists):
    list_of_list = []
    for i in range(0, Nb_of_Lists):
        list_of_list.append(createList())
    return list_of_list

It's working but my List_of_list will not have unique permutations or at least I have no guaranty about it.

Is there any way around to do so? Thanks

Just use islice , which allows you to take a number of elements from an iterable:

from itertools import permutations, islice

n_elements = 1000

list(islice(permutations(x), 0, 1000))

This will return a list of (the first) 1000 permutations.

The reason this works is that permutations returns an iterator , which is an object that generates values to return as they are needed, not immediately. Therefore, the process goes something like this:

  1. The calling function (in this case, list ) asks for the next value from islice
  2. islice checks if 1000 values have been returned; if not, it asks for the next value from permutations
  3. permutations returns the next value, in order

Because of this, the full list of permutations never needs to be generated; we take only as many as we want.

You can do:

i = 0
while i < Nb_of_Lists:
    if createlist() not in list_of_lists:
        list_of_list.append(createList())
    else:
        i -= 1

This will check if that permutation was already used.

You don't need to roll your own permutation. You just to halt the generator once you get enough:

# python 2.7
import random
import itertools
def createList(My_List):
    New_List = random.sample(My_List, len(My_List))
    return New_List

x = createList(xrange(20))
def getFirst200():
    for i, result in enumerate(itertools.permutations(x)):
        if i == 200:
            raise StopIteration
        yield result

print list(getFirst200()) # print first 200 of the result

This is faster and more memory efficient than 'generate of full set then take first 200' approach

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM