在Python中不使用最后n个值生成随机数
我有一个Python函数,它生成一个介于0和100之间的随机数:在Python中不使用最后n个值生成随机数,python,random,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,88,2。。。(当函数得到一个随机数2时,我需要它再试一次,因为2之前已经返回了3个数字) 89,23
def get_next_number():
value = randint(0,100)
每次调用此函数时,我都需要它返回一个随机数,但该数不能是它返回的最后n个随机数之一(本例中假设为5)
以下是一些例子:
55、1、67、12、88、91、100、54(这很好,因为返回的最后5个数字没有重复)
77,42,2,3,88,2。。。(当函数得到一个随机数2时,我需要它再试一次,因为2之前已经返回了3个数字)
89,23,29,81,99100,6,8,23。。。(这一次没有问题,因为23次之前发生了5次以上)
随机函数中有什么东西可以实现这一点吗?反过来想想
与生成随机数然后检查之前是否已生成该随机数不同,您可以首先生成非重复数集,以便逐个拾取,从而消除生成重复数的可能性
您还需要跟踪生成的最后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)
逐步解释:
s = set(range(0, 100))
last5 = []
reduced_list = list(s - set(last5))
缩减列表
中选择随机数,保留在缩减列表
中的所有数字均有效。将编号追加到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
last5
列表中是否已有成员>5。如果是,您需要先删除其成员:
if len(last5) > 5:
last5.pop(0)
return reduced_list[i]
为了实现这一点,可以使用迭代器。下面是该应用程序的示例代码:
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
你需要多少随机数 使用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
保存最后五个数字,并告诉程序在匹配时获取一个新的随机数。不确定这是否有效。当我去生成第12个数字时,它可能是最后使用的5个数字之一。@user1624184好的,我的答案已更新。请再次检查Hanks,这是有道理的,但我一直收到这个错误:last5.append(reduced_s[I])indexer:list index out of therange@user1624184对不起,忘记把
-1
放在那里了。。。更新。请试一试again@user1624184i=randint(0,len(精简列表)-1)#获取任何有效索引-1是必需的,因为randint上限是包含的
我不需要每次都使用唯一的随机数。调用函数5次后,我希望随机数再次可用。在迭代器中使用上述逻辑,并在需要刷新迭代器函数中添加的值时调用新的迭代器对象。验证它,它正在工作。早些时候它有一些问题。刚刚更新了代码