songsinuo 发表于 2021-6-6 14:45:04

random模拟微信发红包

import random
def hongbao(total,num):
    each=[]
    already=0
    for i in range(1,num):
      t=random.randint(1,(total-already)-(num-i))
      each.append(t)
      already=already+t
    each.append(total-already)
    return each
if __name__=='__main__':
    total=300
    num=5
    for i in range(10):
      each=hongbao(total,num)
      print(each)


哪个大神能帮忙详细解释一下这个程序,促进一下理解
能看懂但是自己写就不会了{:5_107:}

suchocolate 发表于 2021-6-6 19:31:32

pycharm开debug自己看过程就行

阿奇_o 发表于 2021-6-7 09:57:35

本帖最后由 阿奇_o 于 2021-6-7 11:24 编辑

"能看懂",但“自己写就不会” ?——那你到底是看没看懂呀。。{:10_250:}

建议可以自己先写写代码注释,然后理清基本思路和步骤。

下面是我的做法:
# 抢红包 v0.8
import random
def hongbao(total, num):# 发多少钱的红包,有多少个人抢红包
    while True:
      each = random.choices(range(1, total), k=num)# 存储每个人分别抢到了多少
      if sum(each) == total:
            break # 保证总和为红包金额,才退出循环
    return each

print(hongbao(10, 5))# 测试:发10块钱红包,5个人抢(每个人都有)

#注: 用randint等随机生成再验证,似乎效率很低,难以保证快速生成总和为红包金额的each序列。
   故采用了choices(),它的效率足够。


qq1151985918 发表于 2021-6-7 16:29:55

本帖最后由 qq1151985918 于 2021-6-7 16:40 编辑

# 首先要看懂整片代码的意义,得一句一句代码分析
# 并且揣摩写代码人的用意
# 这个代码是有比较明显缺陷的
# 缺陷就是 越是前边领取红包的人领取的金额越大
# 越是后边领取红包的人领取的金额越小
# 代码案例中 取 num = 5 就已经很明显了
# 预计代码如果取 num = 20 就没法看了

# 加载模块
import random

# 定义函数 total 为红包总金额 num 为红包个数
def hongbao(total,num):
   
    # each 这里的作用就是储存已经领取的红包金额和人数
    # 如果第一个人领取了 1 块钱,each 就变成
    # 如果第二个人领取了 2 块钱,each 就变成
    each=[]
   
    # already 这里的作用是计算已经领取的红包金额
    # 如果第一个人领取了 1 块钱,already 就变成 1
    # 如果第二个人领取了 2 块钱,already 就变成 3
    # total-already 表示剩余未被领取的金额
    already=0

    # 这里用的 range(1,num) 其实是有深意的
    # 故意少算了一个红包,因为用这个代码
    # 无法保证最后一个人拿到全部的剩余金额
    # 所以在最后又单独加了一个 each.append(total-already)
    # 将全部剩余金额都分配给最后领取的人
    for i in range(1,num):

      # 我们知道 randint 的取值是比较特殊的
      # 一般我们认知的取值区间都是 左闭右开
      # 但是 randint 的取值是 全闭区间
      # 这也是为什么在上面说的要把红包分配少一个人的原因之一
      # 也是下边代码 最后 -(num-i) 的原因
      # 写代码的人的想法是,要保证领取红包的人最少能够领取 1 元
      # 不知道你能不能看懂
      # 全部代码最有深度的就是下边的这一行代码
      # 一定要把这一行代码吃透
      # 这一行代码保证了每个领取到红包的人最少领取到 1 块钱
      # total-already 表示剩余未领取的钱
      # range(1,num) 是取不到 num 的值的,只能取到 num - 1
      # 如果确实看不懂再问吧
      t=random.randint(1,(total-already)-(num-i))

      # 将已经领取的红包储存
      each.append(t)

      # 更新已经领取的金额 already
      already=already+t

    # 将最后剩余金额全部分配给最后一个领取到红包的人
    each.append(total-already)
   
    # 将红包信息返回
    return each
if __name__=='__main__':
    total=300
    num=5

    # 模拟 10 次红包 均为 300 元 5 人
    for i in range(10):
      each=hongbao(total,num)
      print(each)
页: [1]
查看完整版本: random模拟微信发红包