美文网首页
Python基础 random 模块

Python基础 random 模块

作者: 态度哥 | 来源:发表于2019-12-20 10:29 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:Python基础 random 模块

          本文链接:https://www.haomeiwen.com/subject/pqmbnctx.html