Python实现按指定条件从员工列表中随机选取人员
问题描述
需要开发一个Python函数,从包含Manager、Assist、Emp三类的员工列表中随机选取指定总数的人员,要求满足预设的各类人员数量要求:
- 若对应类别人员数量不足,需用其他类别人员补充以满足总数要求(前提是列表总长度≥选取总数)
- 补充优先级为Emp优先
目前尝试通过拆分列表实现,但认为该方式不够高效,寻求优化开发方案。
附现有随机选取代码:
import random list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"] random.shuffle(list_sample) total_num=4 temp_re_list=list_sample[:total_num]
示例需求场景:
# 场景1:各类人员充足,满足预设数量 list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"] total_num=6 manager_num=1 assist_num=2 emp_num=3 # 场景2:Manager数量不足,需用Emp补充 list_sample=["Assist 1","Assist 2","Assist 4","Emp 2","Emp 3","Emp 5","Emp 6"] manager_num=1 assist_num=2 total_num=3
优化实现方案
核心思路
- 高效分类:用字典一次性完成员工分类,避免多次遍历列表
- 按需取数:先按需求提取各类人员,不足则取现有全部
- 缺口补充:优先用Emp填补缺口,再依次用Assist、Manager(若Emp不足)
- 随机打乱:最终结果打乱,保证随机性
完整代码
import random from collections import defaultdict def select_employees(employee_list, total_num, manager_req=0, assist_req=0, emp_req=0): # 1. 一次遍历完成员工分类 category_map = defaultdict(list) for emp in employee_list: if "Manager" in emp: category_map["Manager"].append(emp) elif "Assist" in emp: category_map["Assist"].append(emp) elif "Emp" in emp: category_map["Emp"].append(emp) # 2. 按需求抽取各类人员,不足则取全部可用 selected = [] # 处理Manager需求 take_manager = min(manager_req, len(category_map["Manager"])) selected.extend(random.sample(category_map["Manager"], take_manager)) # 处理Assist需求 take_assist = min(assist_req, len(category_map["Assist"])) selected.extend(random.sample(category_map["Assist"], take_assist)) # 处理Emp需求 take_emp = min(emp_req, len(category_map["Emp"])) selected.extend(random.sample(category_map["Emp"], take_emp)) # 3. 计算缺口并按优先级补充 remaining = total_num - len(selected) if remaining > 0: # 优先用剩余Emp补充 remaining_emp = category_map["Emp"][take_emp:] take_from_emp = min(remaining, len(remaining_emp)) selected.extend(random.sample(remaining_emp, take_from_emp)) remaining -= take_from_emp # Emp不足时用剩余Assist补充 if remaining > 0: remaining_assist = category_map["Assist"][take_assist:] take_from_assist = min(remaining, len(remaining_assist)) selected.extend(random.sample(remaining_assist, take_from_assist)) remaining -= take_from_assist # 最后用剩余Manager补充 if remaining > 0: remaining_manager = category_map["Manager"][take_manager:] take_from_manager = min(remaining, len(remaining_manager)) selected.extend(random.sample(remaining_manager, take_from_manager)) # 4. 打乱结果保证随机性 random.shuffle(selected) return selected[:total_num] # 极端情况兜底,确保不超总数
测试示例
场景1:各类人员充足
list_sample = ["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"] result = select_employees(list_sample, total_num=6, manager_req=1, assist_req=2, emp_req=3) print("场景1结果:", result) # 示例输出:['Manager 2', 'Assist 3', 'Assist 1', 'Emp 5', 'Emp 2', 'Emp 4']
场景2:Manager数量不足,需用Emp补充
list_sample = ["Assist 1","Assist 2","Assist 4","Emp 2","Emp 3","Emp 5","Emp 6"] result = select_employees(list_sample, total_num=3, manager_req=1, assist_req=2) print("场景2结果:", result) # 示例输出:['Assist 2', 'Emp 3', 'Assist 1'] (自动补充1个Emp)
优化点说明
- 分类阶段仅遍历一次列表,比原拆分方案更高效
- 使用
random.sample直接随机抽取指定数量,无需提前打乱整个列表 - 补充逻辑严格按优先级执行,避免冗余判断
- 用
defaultdict简化分类字典的初始化,代码更简洁
内容的提问来源于stack exchange,提问作者new_dev
相关产品推荐
相关产品推荐

