Random模块

random模块 python 中获取随机数的模块.
列出几个常用函数
import random

random.random() 随机一个 0-1直接的浮点数,闭区间,不包括0和1 永远是 0.*****

ret1 = random.random() # (0,1)
print(ret1) #0.9171884476077912

ret2 = random.random() # (0,1)
print(ret2) #0.41349076378970284

random.randint(a,b) 随机获取一个 a-b区间的整数,开区间. 包括a和b

ret1 = random.randint(100,200)
print(ret1) #112

ret2 = random.randint(100,200)
print(ret2) #186

random.randrange(a,b,k)随机获取一个a-(b-1)区间的整数(range顾头不顾尾),k为相隔的个数,1:不隔数;2:隔一个取一个;3:隔两个取一个…

ret1 = random.randrange(1,20,2) # 获取一到20直接的奇数(最大19最小1)
print(ret1) # 15

ret2 = random.randrange(1,20,1) # 获取一到20直接的整数
print(ret2) # 4

random.shuffle(x, random=None) 打乱顺序,如发牌

lst = [1,2,3,4,5,6,7]
random.shuffle(lst)
print(lst) # [4, 6, 7, 1, 5, 2, 3]

l = [‘a’,‘b,’‘c’,‘d’,‘e’,‘f’]
random.shuffle(l)
print(l) #[‘f’, ‘d’, ‘b,c’, ‘a’, ‘e’]

random.choice()随机抽取一个

ret = random.choice([1,2,‘a’,‘f’,[1,2,3]])
print(ret) # 2

ret = random.choice([1,2,‘a’,‘f’,[1,2,3]])
print(ret) # [1,2,3]

random.sample(l, k)随机抽取多个值,k要小于l的长度,返回由k个元素组成新的列表

ret = random.sample([1,2,‘a’,‘f’,5,[1,2,3]],2)
print(ret) #[5,1]

ret1 = random.sample([1,2,‘a’,‘f’,5,[1,2,3]],2)
print(ret1) #[‘a’, [1, 2, 3]]

生成随机验证码 纯数字 或 数字➕字符

import random

def code(n=4,alpha=True): # 默认4位,有字符的验证码
s = ‘’
for i in range(n):
num = random.randint(0, 9)
if alpha: #判断是否纯数字
alpha_lower = chr(random.randint(97,122)) #得到一个随机的小写字母
alpha_upper = chr(random.randint(65,90)) #得到一个随机的大写字母
num = random.choice([num,alpha_upper,alpha_lower]) #随机返回一个
s += str(num) #拼接
return s

ret = code()
print(ret)

ret = code(6)
print(ret)

ret = code(alpha=False)
print(ret)

ret = code(6,False)
print(ret)

结果
xTLK
WZ3Ii1
3495
938403

发红包 拼手气红包
200元 10个 每个人抢到的钱都是随机的

每一个人抢到多少钱的概率都平均
先看下图,其实是一个比较简单的数学问题:

self

图上的意思是这样的:

n个人,随机获取n-1不重复的0-200之间的整数,然后对这些数排序,因为他肯定会在0-200的范围内,所有把这些值在0-200之间标注出来后,就相当于把0-200是分成了n段(加上头和尾的数是n+1个数,n段),这样每一段就是每个人随机抢到的红包数,再把每一段的值相加肯定为200.这样思路是不是就通了,每个人获得多钱的概率是一样的,上图最后一个人随机抢到了104 ,也是运气爆表. 下面来写代码:
import random

def za_send_RedEnvelope(money,n):
lst = []
#随机获取n-1个不重复的整数
ret = random.sample(range(1,money),n-1)
#对随机数排序
ret.sort()
#插入头0和尾部最大值money
ret.insert(0,0)
ret.append(money)
#用后一个数减去前一个数,获取每个人的红包数
for i in range(len(ret)-1):
val = ret[i+1]-ret[i]
lst.append(val)
return lst

ret = za_send_RedEnvelope(200,10)
print(ret) #[5, 9, 9, 69, 3, 20, 29, 30, 23, 3]
print(sum(ret)) #200

上面代码可以看到,得到的十个整数,相加是200,但是实际发红包的时候,最小的应该是1分钱而不是上面的1块钱.下面我们把单位换算一下,1块钱=100分钱,所以代码改成下面的样子(不要直接使用flost因为经常会算错的,直接换算单位是最准确的做法):
import random

def za_send_RedEnvelope(money,n):
lst = []
#把money换算成分 1 块钱 = 100分钱
money = money * 100
#随机获取n-1个不重复的整数
ret = random.sample(range(1,money),n-1)
#对随机数排序
ret.sort()
#插入头0和尾部最大值money
ret.insert(0,0)
ret.append(money)
#用后一个数减去前一个数,获取每个人的红包数
for i in range(len(ret)-1):
val = ret[i+1]-ret[i]
val = val / 100 #换算单位
lst.append(val)
return lst
ret = za_send_RedEnvelope(200,10)
print(ret)
print(sum(ret))

我刷新了好几次结果如下:
[15.58, 73.6, 13.95, 6.21, 22.45, 0.13, 21.01, 8.19, 24.95, 13.93]
199.99999999999997

[41.51, 15.06, 6.48, 29.64, 5.26, 12.15, 27.97, 9.56, 3.12, 49.25]
200.0

[0.59, 23.46, 50.58, 0.34, 9.13, 14.65, 8.0, 31.43, 5.08, 56.74]
200.00000000000003

上面显示不是200的结果,是因为小数以二进制形式表示时的有穷性导致的.这个问题,就不在这里说了,可以搜索下decimal模块自己去了解下怎么解决这种问题 .
计算机的内存、cpu寄存器等等这些硬件单元都是有限的,只能表示有限位数的二进制位,因此存储的二进制小数就会和实际转换而成的二进制数有一定的误差。这个不是python 的问题,所有基于二进制的浮点数都会有这个问题,原因在于大部分浮点数转换为二进制后都是无限循环小数,而浮点数不可能用无限大的内存来储存,所以会有舍入的误差
可以去加一下结果肯定是200.
还有一个场景,因为是抢红包,所有这些数据应该不是一次性全放到内存中去,应该是拿一个取一个,所有这里应该要变成生成器更好一点代码如下:
import random

def za_send_RedEnvelope(money,n):
#把money换算成分 1 块钱 = 100分钱
money = money * 100
#随机获取n-1个不重复的整数
ret = random.sample(range(1,money),n-1)
#对随机数排序
ret.sort()
#插入头0和尾部最大值money
ret.insert(0,0)
ret.append(money)
#用后一个数减去前一个数,获取每个人的红包数
for i in range(len(ret)-1):
val = ret[i+1]-ret[i]
val = val / 100 #换算单位
yield val

ret = za_send_RedEnvelope(200,10)
print(ret)
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(ret.next())
print(’-’*100)
print(‘生成器取完值:’,sum(ret))

结果如下:
<generator object za_send_RedEnvelope at 0x103697318>

11.68
28.39
23.63
35.17
53.03
19.83
8.35
6.79
1.1
12.03

生成器取完值: 0

作者:Day1_
链接:https://www.jianshu.com/p/08574ffdfda3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值