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

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

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

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

前期基础教程:

「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职场效率工具!

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

相关推荐

MySQL进阶五之自动读写分离mysql-proxy

自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...

Postgres vs MySQL_vs2022连接mysql数据库

...

3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?

引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...

一文由浅入深带你完全掌握MySQL的锁机制原理与应用

本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...

验证Mysql中联合索引的最左匹配原则

后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...

MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)

目录1.索引基础...

你会看 MySQL 的执行计划(EXPLAIN)吗?

SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...

MySQL 从入门到精通(四)之索引结构

索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...

mysql总结——面试中最常问到的知识点

mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...

mysql总结——面试中最常问到的知识点(2)

首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...

MySQL基础全知全解!超详细无废话!轻松上手~

本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...

深入剖析 MySQL 中的锁机制原理_mysql 锁详解

在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...

Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析

引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...

MySQL基础篇:DQL数据查询操作_mysql 查

一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...

MySql:索引的基本使用_mysql索引的使用和原理

一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...