Исходя из того, что вы описываете, я считаю, что у вас будет намного более эффективный алгоритм, если вы выберете каждый компонент случайным образом, независимо от других, и продолжите, пока у вас не будет необходимого образца.ГСЧ (генераторы случайных чисел) достаточно быстрые, чтобы восполнить необходимость замены случайного дубликата.Сохраните выбранные вами комбинации в виде набора кортежей (хэшируемого), и вы сможете искать включение набора в постоянное время, делая коллекцию линейным временем.Примерно так:
from random import randint
# For illustration, the "lsits" include letters, symbols, 3-letter words, and low primes
list1 = "pythonic"
list2 = "~!@#$%^&*()"
list3 = ["dog", "cat", "ape", "red", "cwm", "pox"]
list4 = [2, 3, 5, 7, 11, 13, 17, 19]
combo = [list1, list2, list3, list4]
my_sample = set()
needed_size = 10
while len(my_sample) < needed_size:
# Choose one random item from each list; that forms an element
elem = tuple([comp[randint(0, len(comp)-1)] for comp in combo])
# Using a set elminates duplicates easily
my_sample.add(elem)
print(my_sample)
Вывод:
{('h', '$', 'pox', 7),
('y', '(', 'cat', 11),
('n', '@', 'cat', 7),
('i', '^', 'ape', 13),
('y', '#', 'pox', 11),
('o', '%', 'dog', 7),
('p', '^', 'cwm', 13),
('c', '*', 'dog', 19),
('o', ')', 'pox', 11),
('h', '~', 'cat', 5)}
Другая возможность - сгенерировать одно случайное число в диапазоне произведений длин (8 *10 * 6 * 8 в данном случае), а затем используйте целочисленное деление и mod
, чтобы разбить это на четыре случайных индекса.
Еще одна возможность - просто сгенерировать первый набор случайных индексов, а затемувеличивайте их по своему усмотрению, по очереди просматривая списки.В этом случае вы захотите, чтобы длины вашего списка были попарно взаимно простыми;Вы можете гарантировать это, добавляя элемент None
по мере необходимости.Любая комбинация с None
отбрасывается.
Эти идеи заставляют вас двигаться?