【Python】ValueError:Sample larger than population or is negative的原因

ValueError: Sample larger than population or is negative 的原因以及解决办法

1.出现

这几天重构kook-valorant-bot的代码的时候,遇到了这个问题

Job "vip_roll_task (trigger: interval[0:01:20], next run at: 2023-01-25 19:59:21 CST)" raised an exception
Traceback (most recent call last):
  File "/home/muxue/.local/lib/python3.10/site-packages/apscheduler/executors/base_py3.py", line 30, in run_coroutine_job
    retval = await job.func(*job.args, **job.kwargs)
  File "/home/muxue/kook/val-bot/code/main.py", line 793, in vip_roll_task
    ran = random.sample(range(0, len(VipRollDcit[msg_id]['user']) - 1), vnum)
  File "/usr/local/lib/python3.10/random.py", line 482, in sample
    raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
error raised during task
Traceback (most recent call last):
  File "/home/muxue/.local/lib/python3.10/site-packages/apscheduler/executors/base_py3.py", line 30, in run_coroutine_job
    retval = await job.func(*job.args, **job.kwargs)
  File "/home/muxue/kook/val-bot/code/main.py", line 793, in vip_roll_task
    ran = random.sample(range(0, len(VipRollDcit[msg_id]['user']) - 1), vnum)
  File "/usr/local/lib/python3.10/random.py", line 482, in sample
    raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative

这部分代码是用来生成抽奖结果的随机数的,在网上百度了报错之后,得知是random生成随机数时产生的报错

2.复现

找到对应的代码

ran = random.sample(range(0, len(VipRollDcit[msg_id]['user'])-1), vnum) # 生成n个随机数

这个代码的作用是,生成vnum个从0到len(VipRollDcit[msg_id]['user']) - 1的随机数,不包含len(VipRollDcit[msg_id]['user'])-1

咳咳,这里又发现了另外一个bug:我以为是包含右边界的,所以手动-1了;现在导致最后一个参加抽奖的用户永远都抽不到奖了😥

正确的range应该是(0, len(VipRollDcit[msg_id]['user']))

但是,如果参与抽奖的人数少于vnum,就会出现上面的报错

import random
ran = random.sample(range(0, 2), 3) 

可以来简单测试一下,这里我想在0到2之间(其实就是0,1)生成3个随机数

$ py3 test1.py
Traceback (most recent call last):
  File "/home/muxue/kook/test/global_val_test/test1.py", line 16, in <module>
    ran = random.sample(range(0, 2), 3) 
  File "/usr/local/lib/python3.10/random.py", line 482, in sample
    raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative

此时运行,就会有这样的报错。

因为这个写法的作用是在0-2之间产生不重复的随机数,你的目标数量都大于这个集合之中已有数据的数量了,那要怎么生成不重复的随机数呢?

3.解决

解决办法很简单

  • 右边界不能等于或者小于左边界
  • 产生随机数的数量要小于边界之中数据的数量

比如上面的代码,我们修改一下边界,就能获得正确的结果

import random
ran = random.sample(range(0, 3), 3) 
print(ran)

运行

$ py3 test1.py
[0, 2, 1]

对于我的抽奖代码而言,则需要重新操作一番。即可能出现奖品数量大于参与抽奖的人数的情况;

这时候就需要进行判断了

  • 奖品数量少于抽奖人数,使用random生成随机数
  • 奖品数量大于抽奖人数,抛弃多余奖品,直接生成一个从0到总人数的列表
  • 奖品数量等于抽奖人数,上面两种情况都可以用

代码如下

# 人数大于奖品数量
if len(VipRollDcit[msg_id]['user'])>vnum: 
	ran = random.sample(range(0, len(VipRollDcit[msg_id]['user'])), vnum) # 生成vnum个随机数
else: # 生成一个从0到len-1的列表 如果只有一个用户,生成的是[0]
	ran = list(range(len(VipRollDcit[msg_id]['user'])))

这时候就ok了,没有问题了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕雪华年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值