Python实现公司秘密好友抽签系统:解决重复抽签问题
解决秘密好友抽签系统中一人被多次抽中的问题
原代码问题分析
- 排列使用逻辑错误:直接遍历
permutations生成的全排列,却固定取第2、3个元素输出,完全没有构建有效的一一配对关系,导致重复分配,出现一人被多人抽中的情况。 - CSV表头处理不当:对所有CSV数据合并后统一
pop(0),若存在多个CSV文件,会错误删除多条数据,而非每个文件单独跳过表头。
修正方案
我们需要生成无自环的完美配对:每个员工恰好抽到一位秘密好友,且每个员工仅被一人抽到,同时避免抽中自己。以下是实现代码:
import glob import random import csv def generate_valid_pairing(employees): # 生成无自环的完美抽签配对 while True: shuffled = employees.copy() random.shuffle(shuffled) # 检查是否存在员工抽中自己的情况 no_self_pair = all(emp[1] != paired[1] for emp, paired in zip(employees, shuffled)) if no_self_pair: return list(zip(employees, shuffled)) # 读取所有CSV文件,正确跳过每个文件的表头 all_employees = [] for file_path in glob.glob("random_friend/csv/*"): with open(file_path, "r", newline='', encoding='utf-8') as f: reader = csv.reader(f, delimiter=',') next(reader) # 跳过当前文件的表头行 all_employees.extend(row for row in reader) # 生成有效的抽签配对 pairings = generate_valid_pairing(all_employees) # 礼物选项(也可直接使用员工填写的心仪礼物:receiver[3],对应CSV中第四列) gift_options = ['chocolat', 'Squeeze', 'fridge magnet', 'popcorn door cushion kit', 'cocktail shaker kit', 'Suspense book'] # 输出配对结果(后续可替换为发送邮件的逻辑) for giver, receiver in pairings: giver_name = giver[1] receiver_name = receiver[1] receiver_email = receiver[2] selected_gift = random.choice(gift_options) print(f"{giver_name} 的秘密好友是 {receiver_name},请发送虚拟礼物「{selected_gift}」到邮箱:{receiver_email}")
关键逻辑说明
- 有效配对生成:通过随机打乱员工列表,循环检查直到不存在自环(抽中自己),确保每个员工仅被分配一次,形成合法的抽签闭环。
- CSV读取优化:使用
with语句安全管理文件,每个文件单独跳过表头,避免多文件场景下的数据错误。 - 灵活礼物分配:既可以随机选择礼物,也可以直接使用员工填写的心仪礼物(对应CSV中第四列,索引为3)。
内容的提问来源于stack exchange,提问作者Maycon Batestin
相关产品推荐
相关产品推荐

