最近编写一个模拟游戏抽奖的程序,需要使用到标准库random模块,但是使用的时候出现了一个很大的问题,游戏中的抽奖概率是2.23%,是一个二位小数,并带有百分号,化成小数是0.0223,也就是说一万次抽奖中约有223次抽中,如果把所有的抽奖结果放进一个列表并用random.choice函数的话,那需要一万项,其中223项为目标结果,这样对于程序员来说工作量实在太大,所以应该编写一个对每个事件制定一个概率,让程序按照概率进行抽奖的函数。
在这里给大家推荐一个比较好的方法,可以实现每个事件有对应的出现概率: 注:在代码块中events是所有可能出现的事件的列表,values是每个事件的概率的列表,和events一一对应,points是所有点的列表,num则是挨个检查是否符合事件的一个不起眼的变量。
from random import *
def sampling(dictionary):
#本函数的原理是代数化的几何概率
'''按照参数所指定的概率随机抽取一个元素,传入的参数始终是一个字典
其中键为事件,值为事件发生的概率,所有的值必须是介于0和1的浮点数
且所有值的和应为1,若不是这样,则抛出异常。
不支持无法化为有限小数的分数'''
events=[]
values=[]
for i in dictionary:
events.append(i)#将事件从字典中分离出来,因为dictionary.keys()返回的不是一个列表
values.append(dictionary[i])#将每个事件的概率也分离出来,与事件一一对应
if sum(values)!=1:#如果概率加起来并不是1,则抛出异常
raise ValueError('All values must be float numbers between 0 and 1 and the sum of all values should be 1.')
points=[]
for i in values:
point=0
a=values.index(i)
while a>=0:#下面将参数中提供的每个事件的概率转换为一个个类似数轴上的点
point+=values[a]
a-=1
points.append(point)
points.insert(0,0)#把数轴原点0也加入列表
#假设在数轴上,第一个点是0,第一个点和第二个点的距离是第一个事件的概率
#第二个点到第三个点的距离是第二个事件的概率,所以第三个点在数轴上的值是前两个事件概率的和,以此类推
result=random()#在0到1之间选取一个数
for num in points:
if num |