Вопрос-Ответ

How do I create a list of random numbers without duplicates?

Как мне создать список случайных чисел без дубликатов?

Я пытался использовать random.randint(0, 100), но некоторые числа были одинаковыми. Существует ли метод / модуль для создания списка уникальных случайных чисел?

Переведено автоматически
Ответ 1

Это вернет список из 10 чисел, выбранных в диапазоне от 0 до 99, без дубликатов.

import random
random.sample(range(100), 10)
Ответ 2

Вы можете использовать функцию shuffle из модуля random следующим образом:

import random

nums = list(range(1, 100)) # list of integers from 1 to 99
# adjust this boundaries to fit your needs
random.shuffle(nums)
print(nums) # <- List of unique random numbers

Обратите внимание, что метод shuffle не возвращает никакого списка, как можно было бы ожидать, он только перетасовывает список, переданный по ссылке.

Ответ 3

Вы можете сначала создать список чисел от a до b, где a и b соответственно наименьшие и наибольшие числа в вашем списке, затем перетасовать его с помощью алгоритма Фишера-Йейтса или с помощью random.shuffle метода Python.

Ответ 4

Линейный конгруэнтный генератор псевдослучайных чисел


O (1) Память


O (k) операций


Эта проблема может быть решена с помощью простого линейного конгруэнтного генератора. Это требует постоянных затрат памяти (8 целых чисел) и не более 2 * (длина последовательности) вычислений.

Все другие решения требуют больше памяти и вычислительных ресурсов! Если вам нужно всего несколько случайных последовательностей, этот метод будет значительно дешевле. Для диапазонов размера N, если вы хотите генерировать порядка N уникальных k последовательностей или больше, я рекомендую принятое решение с использованием встроенных методов, random.sample(range(N),k) поскольку это было оптимизировано в python для повышения скорости.

Код

# Return a randomized "range" using a Linear Congruential Generator
# to produce the number sequence. Parameters are the same as for
# python builtin "range".
# Memory -- storage for 8 integers, regardless of parameters.
# Compute -- at most 2*"maximum" steps required to generate sequence.
#
def random_range(start, stop=None, step=None):
import random, math
# Set a default values the same way "range" does.
if (stop == None): start, stop = 0, start
if (step == None): step = 1
# Use a mapping to convert a standard range into the desired range.
mapping = lambda i: (i*step) + start
# Compute the number of numbers in this range.
maximum = (stop - start) // step
# Seed range with a random integer.
value = random.randint(0,maximum)
#
# Construct an offset, multiplier, and modulus for a linear
# congruential generator. These generators are cyclic and
# non-repeating when they maintain the properties:
#
# 1) "modulus" and "offset" are relatively prime.
# 2) ["multiplier" - 1] is divisible by all prime factors of "modulus".
# 3) ["multiplier" - 1] is divisible by 4 if "modulus" is divisible by 4.
#
offset = random.randint(0,maximum) * 2 + 1 # Pick a random odd-valued offset.
multiplier = 4*(maximum//4) + 1 # Pick a multiplier 1 greater than a multiple of 4.
modulus = int(2**math.ceil(math.log2(maximum))) # Pick a modulus just big enough to generate all numbers (power of 2).
# Track how many random numbers have been returned.
found = 0
while found < maximum:
# If this is a valid value, yield it in generator fashion.
if value < maximum:
found += 1
yield mapping(value)
# Calculate the next value in the sequence.
value = (value*multiplier + offset) % modulus

Использование

Использование этой функции "random_range" такое же, как и для любого генератора (например, "range"). Пример:

# Show off random range.
print()
for v in range(3,6):
v = 2**v
l = list(random_range(v))
print("Need",v,"found",len(set(l)),"(min,max)",(min(l),max(l)))
print("",l)
print()

Примеры результатов

Required 8 cycles to generate a sequence of 8 values.
Need 8 found 8 (min,max) (0, 7)
[1, 0, 7, 6, 5, 4, 3, 2]

Required 16 cycles to generate a sequence of 9 values.
Need 9 found 9 (min,max) (0, 8)
[3, 5, 8, 7, 2, 6, 0, 1, 4]

Required 16 cycles to generate a sequence of 16 values.
Need 16 found 16 (min,max) (0, 15)
[5, 14, 11, 8, 3, 2, 13, 1, 0, 6, 9, 4, 7, 12, 10, 15]

Required 32 cycles to generate a sequence of 17 values.
Need 17 found 17 (min,max) (0, 16)
[12, 6, 16, 15, 10, 3, 14, 5, 11, 13, 0, 1, 4, 8, 7, 2, ...]

Required 32 cycles to generate a sequence of 32 values.
Need 32 found 32 (min,max) (0, 31)
[19, 15, 1, 6, 10, 7, 0, 28, 23, 24, 31, 17, 22, 20, 9, ...]

Required 64 cycles to generate a sequence of 33 values.
Need 33 found 33 (min,max) (0, 32)
[11, 13, 0, 8, 2, 9, 27, 6, 29, 16, 15, 10, 3, 14, 5, 24, ...]
python