生成随机数而不使用Python中的最后n个值

时间:2016-02-25 05:23:41

标签: python random

我有一个Python函数,可以生成0到100之间的随机数:

def get_next_number():
    value = randint(0,100)

每次调用此函数时,我都需要它返回一个随机数,但该数字不能是它返回的最后n个随机数之一(假设这个例子为5)。

以下是一些例子:

55,1,67,12,88,91,100,54(这很好,因为返回的最后5个数字没有重复)

77,42,2,3,82,2 ......(当函数得到2的随机数时,我需要它再试一次,因为2之前已经返回3个数字)

89,23,29,81,99,100,6,8,23 ......(这个很好,因为23次发生超过5次)

随机功能中是否有内置功能来实现这一目标?

3 个答案:

答案 0 :(得分:1)

想一想反过来

不是生成随机数,然后检查之前是否已生成,您可以先生成一组非重复数字,然后通过一个 - 从而消除了生成重复数字的可能性。

您还需要跟踪生成的最后5个项目,以便从挑选的项目中排除它们。

这样的事情会:

s = set(range(0, 100))
last5 = []
def get_next_number():
    reduced_list = list(s - set(last5))
    i = randint(0, len(reduced_list) - 1)
    last5.append(reduced_list[i])
    if len(last5) > 5:
        last5.pop(0)
    return reduced_list[i]

测试:

result = []
for i in range(0, 5000):
    result.append(get_next_number())
print(result)

分步说明:

  1. 生成要拾取的数字集(例如,0到99)并生成一个空列表来存储最后5个选中的数字:

    s = set(range(0, 100))
    last5 = []
    
  2. 在该方法中,从被挑选的可能性中排除最后5个选中的数字:

    reduced_list = list(s - set(last5))
    
  3. reduced_list中选择随机数,reduced_list中剩下的所有数字都有效。将数字附加到last5列表

    i = randint(0, len(reduced_list) - 1) #get any valid index. -1 is needed because randint upperbound is inclusive
    last5.append(reduced_list[i]) #the number is as what it pointed by the index: reduced_list[i], append that number to the last 5 list
    
  4. 检查last5列表是否已有成员> 5.如果是,您需要删除第一个成员:

    if len(last5) > 5:
        last5.pop(0)
    
  5. 返回您选择的成员:

    return reduced_list[i]
    

答案 1 :(得分:0)

为实现此目的,您可以使用迭代器。以下是该示例代码:

import random

class UniqueRandom(object):
    def __init__(self, num):
        self.unused_nums = range(num)
        self.num = num

    def __iter__(self):
        return self

    def next(self):
        if self.num:
            random_num = random.randrange(self.num)
            unique_num = self.unused_nums[random_num]
            self.unused_nums[random_num], self.unused_nums[self.num-1] = self.unused_nums[self.num-1], self.unused_nums[random_num]
            self.num -= 1
            return unique_num
        else:
            raise StopIteration

例如,要生成0到100之间的随机数:

random_num = UniqueRandom(100)
print next(random_num)  # 54
print next(random_num)  # 33

要刷新值,请创建新的迭代器对象:

random_num = UniqueRandom(100)
print next(random_num)  # 92
print next(random_num)  # 33 (repeated)

您也可以在列表中使用它:

>>> for i in UniqueRandom(5):
...     print i
... 
2
1
0
3
4

答案 2 :(得分:0)

您需要多少个随机数?

使用Python的内置random.sample方法。它列出了从人口序列或集合中选择的唯一元素,用于随机抽样而无需替换。

>>> import random
>>> random.sample(range(1, 100), 3)
[56, 43, 74]

创建一个包含随机整数的大型列表。然后,pop()在需要时。

>>> rands = random.sample(range(1, 100), 20)
>>> rands
[63, 23, 68, 72, 18, 83, 56, 34, 19, 7, 51, 5, 89, 47, 26, 49, 2, 1, 93, 84]
>>> rands.pop()
84
>>> rands.pop()
93