Конечные перестановки списка питонов - PullRequest
2 голосов
/ 13 апреля 2019

У меня есть список, и я хотел бы создать конечное число перестановок без повторяющихся элементов.

itertools.permutations(x)

дает все возможные упорядочения, но мне нужно только определенное количество перестановок.(мой первоначальный список содержит ~ 200 элементов => 200! это займет неоправданное количество времени, и мне не нужны все из них)

что я уже сделал

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

Это работает, но у моего List_of_list не будет уникальных перестановок или, по крайней мере, у меня нет никаких гарантий по этому поводу.

Есть ли способ сделать это?Спасибо

Ответы [ 3 ]

5 голосов
/ 13 апреля 2019

Просто используйте islice, что позволяет вам взять несколько элементов из итерируемого:

from itertools import permutations, islice

n_elements = 1000

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

Это вернет list из (первой) 1000 перестановок.

Причина, по которой это работает, заключается в том, что permutations возвращает итератор , который является объектом, который генерирует значения, которые возвращаются по мере необходимости, а не сразу. Поэтому процесс идет примерно так:

  1. Вызывающая функция (в данном случае list) запрашивает следующее значение из islice
  2. islice проверяет, было ли возвращено 1000 значений; если нет, то запрашивается следующее значение из permutations
  3. permutations возвращает следующее значение в порядке

Из-за этого полный список перестановок никогда не нужно генерировать; мы берем только столько, сколько хотим.

1 голос
/ 13 апреля 2019

Вам не нужно бросать свою собственную перестановку. Вы просто останавливаете генератор, когда получаете достаточно:

# 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

Это быстрее и эффективнее с точки зрения использования памяти, чем подход «генерация полного набора, а затем первые 200»

1 голос
/ 13 апреля 2019

Вы можете сделать:

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

Это проверит, использовалась ли уже эта перестановка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...