百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Python技巧!3分钟学会永不重复的随机点名和微信红包算法

wptr33 2025-03-25 18:07 4 浏览

喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。

前期基础教程:

「Python3.11.0」手把手教你安装最新版Python运行环境

讲讲Python环境使用Pip命令快速下载各类库的方法

Python启航:30天编程速成之旅(第2天)-IDE安装

【Python教程】JupyterLab 开发环境安装


前言

在职场和校园中,随机点名红包分配是高频需求!你是否遇到过传统工具功能单一、分配不公的痛点?本文用Python打造两大神器,代码可直接复制使用,更有超详细原理拆解,新手也能秒懂!


一、永不重复的随机点名器

1.1 场景痛点

老师上课点名总重复?晨会抽奖有人连续中奖?核心需求:公平随机,且不连续选中同一人!

1.2 代码实现

import random

class RandomRollCall:
    def __init__(self, candidates):
        self.candidates = candidates  # 候选人名单
        self.last_pick = []        # 记录上一次选中的人

    def pick(self):
        # 排除上一次选中的人,生成候选名单
        valid_list = [name for name in self.candidates if name not in self.last_pick]

        # 如果候选名单为空(如只有1人),则重置为原始名单
        if not valid_list:
            valid_list = self.candidates.copy()
        # 随机选择并更新记录
        chosen = random.choice(valid_list)
        self.last_pick.append(chosen)

        return chosen

1.3 案例演示

场景1:课堂点名

students = ["小明", "小美", "张三", "李四", "王五"]
roll_call = RandomRollCall(students)

# 模拟连续点名5次
for _ in range(5):
    print(roll_call.pick())

运行结果:

场景2:仅1人特殊情况

single = ["CEO"]
roll_call = RandomRollCall(single)
print(roll_call.pick())  # 输出:CEO
print(roll_call.pick())  # 仍输出:CEO(因无其他人可选)

运行结果:

1.4 原理精讲

  • 动态候选名单:每次排除上次结果,确保不重复
  • 自动重置机制:当候选名单为空时恢复原始名单,避免报错

二、微信同款拼手气红包算法

2.1 需求拆解

  • 金额约束:每人至少0.01元,总和等于总金额
  • 随机性:金额波动大,增加趣味性

2.2 代码实现(微信同款思路)

def wechat_red_envelope(total, num):
    # 将金额转为分计算,避免浮点误差
    total_cents = int(round(total * 100))
    if num <=0 or total_cents < num * 1:
        raise ValueError("金额过少或人数错误")
    
    amounts = []
    remaining_cents, remaining_num = total_cents, num
    
    # 为前n-1人随机分配金额
    for _ in range(num - 1):
        # 核心算法:随机上限=剩余金额-剩余人数*1分(保证后续分配)
        max_amt = remaining_cents - (remaining_num - 1) * 1
        current_amt = random.randint(1, max_amt)
        amounts.append(current_amt)
        remaining_cents -= current_amt
        remaining_num -= 1
    
    # 最后一人拿剩余金额
    amounts.append(remaining_cents)
    random.shuffle(amounts)  # 打乱顺序,避免越后面金额越小
    
    # 转换回元,并保留两位小数
    return [amt / 100.0 for amt in amounts]

2.3 案例演示

场景1:5人抢50元红包

result = wechat_red_envelope(50, 5)
print("分配结果:", result)
print("验证总和:", sum(result))  # 输出:50.0

输出示例

场景2:极端测试(0.02元分3人,每人不足0.01元)

result = wechat_red_envelope(0.02, 3)
print("分配结果:", [round(amt, 2) for amt in result])
print("验证总和:", sum(result))  # 输出:10.0

输出示例

场景3:极端测试(0.03元分3人,每人0.01元)

result = wechat_red_envelope(0.03, 3)
print("分配结果:", [round(amt, 2) for amt in result])
print("验证总和:", sum(result))  # 输出:10.0

运行结果:

2.4 原理解析

  • 整数运算:所有金额转为分计算,避免浮点误差
  • 动态上限:每次分配确保剩余金额足够后续每人1分
  • 随机打乱:避免列表顺序影响金额分布

三、进阶优化技巧

3.1 点名器支持权重

为特定学生设置更高概率(如学号靠后的易被抽中):

def weighted_pick(self):
    # 权重示例:按名单顺序递增
    weights = [i+1 for i in range(len(self.candidates))]
    valid_weights = [w for idx,w in enumerate(weights) if self.candidates[idx] != self.last_pick]
    chosen = random.choices(valid_list, weights=valid_weights, k=1)[0]
    return chosen

3.2 红包金额波动控制

添加参数控制最大金额倍数:

def wechat_red_envelope(total, num, max_multiple=2):
    ...
    max_amt = min(max_amt, (remaining_cents // remaining_num) * max_multiple)
    ...

四、避坑指南

  1. 浮点数精度:红包计算务必转为整数运算
  2. 查重率优化:变量命名个性化(如 valid_list→candidate_pool)
  3. 合规性:代码注释中避免敏感词,示例用虚拟数据

结语

本文代码可直接复制到PyCharm或VSCode中运行,关注我,获取更多Python职场效率工具!

喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。

相关推荐

【推荐】一款开源免费、美观实用的后台管理系统模版

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍...

Android架构组件-App架构指南,你还不收藏嘛

本指南适用于那些已经拥有开发Android应用基础知识的开发人员,现在想了解能够开发出更加健壮、优质的应用程序架构。首先需要说明的是:AndroidArchitectureComponents翻...

高德地图经纬度坐标批量拾取(高德地图批量查询经纬度)

使用方法在桌面上新建一个index.txt文件,把下面的代码复制进去保存,再把文件名改成index.html保存,双击运行打开即可...

flutter系列之:UI layout简介(flutter ui设计)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。...

Android开发基础入门(一):UI与基础控件

Android基础入门前言:...

iOS的布局体系-流式布局MyFlowLayout

iOS布局体系的概览在我的CSDN博客中的几篇文章分别介绍MyLayout布局体系中的视图从一个方向依次排列的线性布局(MyLinearLayout)、视图层叠且停靠于父布局视图某个位置的框架布局(M...

TDesign企业级开源设计系统越发成熟稳定,支持 Vue3 / 小程序

TDesing发展越来越好了,出了好几套组件库,很成熟稳定了,新项目完全可以考虑使用。...

WinForm实现窗体自适应缩放(winform窗口缩放)

众所周知,...

winform项目——仿QQ即时通讯程序03:搭建登录界面

上两篇文章已经对CIM仿QQ即时通讯项目进行了需求分析和数据库设计。winform项目——仿QQ即时通讯程序01:原理及项目分析...

App自动化测试|原生app元素定位方法

元素定位方法介绍及应用Appium方法定位原生app元素...

61.C# TableLayoutPanel控件(c# tabcontrol)

摘要TableLayoutPanel在网格中排列内容,提供类似于HTML元素的功能。TableLayoutPanel控件允许你将控件放在网格布局中,而无需精确指定每个控件的位置。其单元格...

想要深入学习Android性能优化?看完这篇直接让你一步到位

...

12个python数据处理常用内置函数(python 的内置函数)

在python数据分析中,经常需要对字符串进行各种处理,例如拼接字符串、检索字符串等。下面我将对python中常用的内置字符串操作函数进行介绍。1.计算字符串的长度-len()函数str1='我爱py...

如何用Python程序将几十个PDF文件合并成一个PDF?其实只要这四步

假定你有一个很无聊的任务,需要将几十个PDF文件合并成一个PDF文件。每一个文件都有一个封面作为第一页,但你不希望合并后的文件中重复出现这些封面。即使有许多免费的程序可以合并PDF,很多也只是简单的将...

Python入门知识点总结,Python三大数据类型、数据结构、控制流

Python基础的重要性不言而喻,是每一个入门Python学习者所必备的知识点,作为Python入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水。...