寻找一种简单有效的方法来在 python 中生成随机数,以便在每 10 个数字序列中数字不会重复



我想知道是否有一种简单有效的方法来在python中生成随机数 因此,其中 10 个的每个序列都将是不同的数字。

我尝试了此选项:

import random
random.randint(0,100)

但是经过几代人,我注意到生成的数字可以一个接一个地重复 所以我尝试使用一组这些数字,它有点解决了这个问题 但是它留下了一些数字,如果我需要特定数量的随机生成的数字,我需要在之后重新生成,但一段时间后,有人建议我使用另一种解决方案:

Randlist = random.sample(range(1,101), k=10)

这很好用,但需要一个整数列表来容纳我的 10 个不同的数字

有没有办法在没有列表的情况下做到这一点,所以它不会像 O(n^2( 及以上那样太复杂?

算法

import random
def randoms():
while True:
yield random.randint(0,9)
def no_repeat(source_iter, length):
seen = set()
cycle_pos = 0
while True:        
n = next(source_iter)
if n not in seen:
yield n
cycle_pos += 1
seen.add(n)
if cycle_pos == length:
seen.clear()
cycle_pos = 0

rep = no_repeat(randoms(), 10)
print([next(rep) for i in range(100)]) # take 100 items from the `rep` iterator and put them into a list

randoms函数是一个生成器,它给出无限数量的随机数。no_repeat函数是一个生成器,它将生成器作为参数并对其进行过滤,以便长度为 10 的每个部分都没有重复。

通过组合这些生成器,您可以创建一个迭代器,该迭代器生成随机数,每个长度为 10 的序列中没有重复。

复杂性

如果您假设可能的随机数的范围远大于"周期长度",那么生成n数是O(n),因为每次迭代都会生成一个随机数,产生它,并将其添加到集合中。假设集合是一个哈希表,则此添加是O(1)的(检查它是否在集合中也是如此(。如果清除一个集合是O(n),那么如果每 10 个操作完成一次并且花费的时间与 10 成正比,那么每次迭代将摊销为O(1)

如果要考虑较小范围的可能数字,那么对于周期长度k,在循环开始时,每次迭代O(1),则发生冲突的概率1/k,然后对于下一次迭代,概率2/k,直到k迭代后重置。 因此它是O(k^2 n),但这个k是固定的(在您的情况下它总是 10(,所以实际上它可以被认为是一个常数因子,使其等价于O(n).

我可能会先生成数字,然后就地洗牌。像这样:

import random
numbers = [*range(10)] * 5
random.shuffle(numbers)
print(numbers)

编辑:如果您希望数字组保持在一起,请改用以下内容:

import random
result = []
for i in range(5):
numbers = [*range(10)]
random.shuffle(numbers)
result.extend(numbers)
print(result)

最新更新