Я пробовал использовать random.randint(0, 100)
, но некоторые цифры совпали. Есть ли метод / модуль для создания списка уникальных случайных чисел?
Примечание. Следующий код основан на ответе и был добавлен после публикации ответа. Это не часть вопроса; это решение.
def getScores():
# open files to read and write
f1 = open("page.txt", "r");
p1 = open("pgRes.txt", "a");
gScores = [];
bScores = [];
yScores = [];
# run 50 tests of 40 random queries to implement "bootstrapping" method
for i in range(50):
# get 40 random queries from the 50
lines = random.sample(f1.readlines(), 40);
Ответы:
Это вернет список из 10 номеров, выбранных из диапазона от 0 до 99, без дубликатов.
Что касается вашего конкретного примера кода, вы, вероятно, захотите прочитать все строки из файла один раз, а затем выбрать случайные строки из сохраненного списка в памяти. Например:
Таким образом, вам нужно фактически прочитать из файла только один раз перед циклом. Это сделать гораздо эффективнее, чем возвращаться к началу файла и
f1.readlines()
снова вызывать его для каждой итерации цикла.источник
Вы можете использовать функцию перемешивания из случайного модуля следующим образом:
Обратите внимание, что метод перемешивания не возвращает никакого списка, как можно было бы ожидать, он только перемешивает список, переданный по ссылке.
источник
Вы можете сначала создать список чисел от
a
доb
, гдеa
иb
являются соответственно наименьшим и наибольшим числами в вашем списке, а затем перемешать его с помощью алгоритма Фишера-Йейтса или метода Pythonrandom.shuffle
.источник
Решение, представленное в этом ответе, работает, но может стать проблематичным с памятью, если размер выборки небольшой, а совокупность огромна (например
random.sample(insanelyLargeNumber, 10)
).Чтобы исправить это, я бы пошел с этим:
источник
random.sample
этот подход используется для небольшого количества выборок из большой совокупности, поэтому проблема с памятью больше не существует. Хотя в то время, когда был написан этот ответ, реализацияrandom.shuffle
могла быть другой.Генератор линейных конгруэнтных псевдослучайных чисел
Эта проблема может быть решена с помощью простого линейного конгруэнтного генератора . Это требует постоянных накладных расходов на память (8 целых чисел) и не более 2 * (длина последовательности) вычислений.
Все остальные решения используют больше памяти и больше вычислений! Если вам нужно всего несколько случайных последовательностей, этот метод будет значительно дешевле. Для диапазонов размера
N
, если вы хотите сгенерировать порядокN
уникальныхk
-последовательностей или более, я рекомендую принятое решение с использованием встроенных методов,random.sample(range(N),k)
поскольку оно было оптимизировано в python для скорости.Код
использование
Использование этой функции "random_range" такое же, как и для любого генератора (например, "диапазон"). Пример:
Образцы результатов
источник
prime
, функция вернет мне только 4 возможных ответа, потому чтоvalue
это единственная случайно выбранная вещь с 4 возможными значениями, когда нам нужно как минимум (4 выберите 2) = 6 (с учетом неслучайного порядка).random_range(2,4)
вернет значения {(1, 0), (3, 2), (2, 1), (0, 3)}, но никогда не вернет пару (3,1) (или (1,3)). Ожидаете ли вы новых случайным образом генерируемых больших простых чисел при каждом вызове функции?random_range(v)
возвращаются кv
уникальным последовательностямv!
)Если список из N чисел от 1 до N генерируется случайным образом, то да, есть вероятность того, что некоторые числа могут повторяться.
Если вам нужен список чисел от 1 до N в случайном порядке, заполните массив целыми числами от 1 до N, а затем используйте перемешивание Фишера-Ятса или Python
random.shuffle()
.источник
Если вам нужно выбрать очень большие числа, вы не можете использовать
range
потому что бросает:
Кроме того, если
random.sample
вы не можете произвести необходимое количество предметов из-за слишком малого диапазонабросает:
Эта функция решает обе проблемы:
Использование с очень большими числами:
Результат образца:
Использование, когда диапазон меньше количества запрошенных элементов:
Результат образца:
Он также работает с отрицательными диапазонами и шагами:
Примеры результатов:
источник
Вы можете использовать библиотеку Numpy для быстрого ответа, как показано ниже -
Данный фрагмент кода перечисляет 6 уникальных чисел в диапазоне от 0 до 5. Вы можете настроить параметры для вашего удобства.
Вывод
Он не накладывает никаких ограничений, как мы видим в random.sample, как указано здесь .
Надеюсь, что это помогает немного.
источник
Приведенный здесь ответ очень хорошо работает как в отношении времени, так и в отношении памяти, но немного сложнее, поскольку он использует расширенные конструкции python, такие как yield. Более простой ответ хорошо работает на практике, но проблема с этим ответом заключается в том, что он может генерировать множество ложных целых чисел до фактического построения требуемого набора. Попробуйте это сделать с PopulationSize = 1000, sampleSize = 999. Теоретически есть шанс, что он не завершится.
В приведенном ниже ответе рассматриваются обе проблемы, поскольку он детерминирован и в некоторой степени эффективен, хотя в настоящее время не так эффективен, как два других.
где функции getElem, percolateUp определены ниже
Наконец, время в среднем составляло около 15 мс для большого значения n, как показано ниже.
источник
random.randint
функцию 3996 раз, а другая - cca. 6000 раз. Не такое уж большое улучшение, да?Чтобы получить программу, которая генерирует список случайных значений без дубликатов, который является детерминированным, эффективным и построен с использованием базовых программных конструкций, рассмотрите функцию,
extractSamples
определенную ниже,Основная идея состоит в том, чтобы отслеживать интервалы
intervalLst
для возможных значений, из которых можно выбрать необходимые элементы. Это детерминировано в том смысле, что мы гарантированно сгенерируем выборку за фиксированное количество шагов (зависит исключительно отpopulationSize
иsampleSize
).Чтобы использовать указанную выше функцию для создания необходимого списка,
Мы также можем сравнить с более ранним решением (для более низкого значения PopulationSize)
Обратите внимание, что я уменьшил
populationSize
значение, поскольку он вызывает ошибку памяти для более высоких значений при использованииrandom.sample
решения (также упоминалось в предыдущих ответах здесь и здесь ). Для приведенных выше значений мы также можем заметить, что этоextractSamples
превосходитrandom.sample
подход.PS: Хотя основной подход похож на мой предыдущий ответ , есть существенные изменения в реализации, а также в подходе с улучшением ясности.
источник
Очень простая функция, которая также решает вашу проблему
источник
Проблема с подходами на основе набора («если случайное значение в возвращаемых значениях, попробуйте еще раз») заключается в том, что их время выполнения не определено из-за коллизий (которые требуют еще одной итерации «попробуйте еще раз»), особенно когда возвращается большое количество случайных значений. из ассортимента.
Альтернативой, не подверженной этой недетерминированной среде выполнения, является следующее:
источник
источник
Если вы хотите убедиться, что добавляемые числа уникальны, вы можете использовать объект Set
если используется версия 2.7 или выше, или импортируйте модуль sets, если нет.
Как отмечали другие, это означает, что числа не являются действительно случайными.
источник
для выборки целых чисел без замены между
minval
иmaxval
:с jax:
источник
n_samples
из них? Что вы мотивируете этим подходом? Можете ли вы объяснить, в чем преимущества вашего подхода по сравнению с любым из большого количества существующих ответов (большинство из них были получены 8 лет назад)?random.shuffle
, получившие наибольшее количество голосов , используют Mersenne Twister, qhich намного медленнее, чем алгоритмы, предлагаемые numpy (и, вероятно, jax). numpy и jax позволяют использовать другие алгоритмы генерации случайных чисел. jax также позволяет jit-компиляцию и дифференциацию, что может быть полезно для стохастической дифференциации. также, что касается «возможно большого» массива, некоторые наиболее популярные ответы делают то же самоеrandom.shuffle
, и я не считаю это греховным в относительном или даже абсолютном смыслеrandom.shuffle
использует Mersenne Twister» - это тасование Фишера-Йетса, как упоминалось в нескольких ответах. Он имеет линейную временную сложность, поэтому он не может быть асимптотически медленнее, чем алгоритмы, предлагаемые любой другой библиотекой, numpy или иначе. Если numpy быстрее, это только потому, что он реализован в C, но это не гарантирует генерации огромной перестановки (которая может даже не поместиться в памяти) только для выбора из нее нескольких элементов. Нет ни одного ответа, кроме вашего, который бы это делал.random
модуль написан на Python, так что вы можете легко просмотреть его исходный код (попробуйтеrandom.__file__
).Из интерфейса командной строки в win xp:
В Канаде проводится лотерея 6/49. Я просто оборачиваю приведенный выше код в lotto.bat и запускаю
C:\home\lotto.bat
или простоC:\home\lotto
.Поскольку число
random.randint
часто повторяется, я используюset
с,range(7)
а затем укорачиваю его до 6.Иногда, если число повторяется более 2 раз, длина результирующего списка будет меньше 6.
РЕДАКТИРОВАТЬ: Однако
random.sample(range(6,49),6)
это правильный путь.источник
источник
print len(result), len(set(result))
. Можно ожидать,result
что уникальные элементы будут присутствовать только один раз при каждой1.0851831788708547256608362340568947172111832359638926... × 10^20
попытке.