需求描述:

这是一个实际生活中遇到的需求,一共有8个人需要在一周的5个工作日值班,每天都需要5个人完成值班任务,其中有一个人是个组长。要求组长在这5天里一共值班4次,其他人员均值班3次,每天的5个值班人员是8个人中的5人随机组合。

分析:

乍一看,好像有点无从下手,咱们细细分析就可以这样考虑,我们假设每个人都有分身术,组长一共有4个分身,其他人均有3个分身,这时正好25个人,组合后正好可以满足5天(25人)的值班要求。我们就可以对这25个假设对象进行随机分组,唯一的要求就是:同一身份的人不能分到一组中(即同一个人的分身不能分到一起)。分5组即可。

Python实现(Python3.7):

import random

# 构建分身数据源(25个分身对象)

def get_source_data():

data = []

for i in range(4):

data.append({"name":"组长", "role":i}) # role表示分身ID

for i in range(7):

for j in range(3):

data.append({"name": "组员" + str(i), "role": j})

return data

# 进行5次选择,选出5组

def group_by_random():

des_list = []

data_list = get_source_data()

for i in range(5): # 分5组

one_list = []

has_selected = {} # 标记某个人是否已经被添加进当前组中

while(len(one_list) < 5): # 直到每组中有5个不同的人(组中最多有同一个人的1个分身)

index = random.randint(0, len(data_list)-1)

person = data_list[index]

# 如果这个人(此处不区分“分身”,只区分“人”)没有被添加到当前组中,就添加该分身到组中,同时删除原数据列表中的这个分身对象

if not has_selected.__contains__(person["name"]):

one_list.append(person["name"])

data_list.pop(index)

has_selected[person["name"]] = True

des_list.append(one_list)

return des_list

if __name__ == '__main__':

for group in group_by_random():

print("分组:", group)

分组结果:

分组: ['组员1', '组长', '组员3', '组员2', '组员5']

分组: ['组员0', '组员4', '组长', '组员6', '组员1']

分组: ['组员5', '组员6', '组长', '组员3', '组员0']

分组: ['组员6', '组员2', '组员4', '组员1', '组员3']

分组: ['组员4', '组长', '组员0', '组员5', '组员2']

Process finished with exit code 0

问题发现与思考:

问题1、如果人数是成百上千甚至更多呢,数据集就会变得更大,总不能再去创建“分身”对象数据集吧!

问题2、对25个元素的数据集进行随机选取5个元素的时候,存在这样一种可能:前3次随机的结果都是同样的5个人, 这样在第4次随机的时候,导致数据集中的人数少于5个,虽然“分身”元素可能足够用。这种情况下,就会概率性地导致程序卡在group_by_random的while循环处,无法结束程序。问题严重啊~~~问题代码如下:

for i in range(5): # 分5组

one_list = []

has_selected = {} # 标记某个人是否已经被添加进当前组中

# 【注意】这里随机选取的时候,有可能出现连续多次选择到相同的5个人,当这个次数达到3次,就会出现意外情况。。。

while(len(one_list) < 5): # 直到每组中有5个不同的人(组中最多有同一个人的1个分身)

index = random.randint(0, len(data_list)-1)

person = data_list[index]

if not has_selected.__contains__(person["name"]):

one_list.append(person["name"])

data_list.pop(index)

has_selected[person["name"]] = True

des_list.append(one_list)

所以我们变换一种思路,“组长”比较特殊,因为他多一次呗被选中的机会,所以我们先把这次机会取出来,放在一边,不管他。这样所有的8个成员都是一样的情况了,每人可以被选择3次,一共24次。

1、搞一个列表存放这8人,并对列表内元素进行随机排序,

2、顺序的回归选取列表中的元素,选取5次,每次选连续的5个元素(例如:第一次选列表的前5个元素,第二次选取接下来的3个元素和列表头部的2个元素,以此类推......)。最后再把最后一组的最后一个数据删除(因为是多选的一个),添加上“组长”元素。这样就选择出了5组元素(在一个列表中,即列表中有5个列表,每个列表又包含5个元素)。

3、显然这是有规则的顺序选取,所以我们需要对这5组元素进行一个随机排序,以达到随机选取的效果。(这可能并不是严格意义上的机会均等随机,但足以满足需求了)

秘书,上代码(优化后):

import random

# 构建数据源

def get_source_data():

"""

获得一个数据列表,其内容为8个成员,其中一个为“组长”,其余为“组员”

:return:

"""

data = ["组员"+str(x) for x in range(7)]

data.append("组长")

return data

# 进行5次选择,选出5组

def group_by_order(data_list):

"""

对列表进行顺序读取,每5个放到一组中,当读取到列表的最后一个值,就跳转到列表的0索引处,继续读取。

最终返回一个包含5个列表的列表

:param data_list:

:return: 一个二维列表:5x5

"""

des_list = []

index = 0

for i in range(5):

group = []

for k in range(5):

group.append(data_list[index])

index += 1

if index > len(data_list)-1:

index = 0

if i is 4:# 对“组长”的情况特殊处理

group.pop(len(group)-1)

group.append("组长")

des_list.append(group)

return des_list

def set_random(data_list):

"""

对一个列表里的值得顺序随机打乱

:param data_list:

:return:

"""

return random.sample(data_list, len(data_list))

if __name__ == '__main__':

data = set_random(get_source_data())

groups = group_by_order(data)

groups = set_random(groups)

for group in groups:

print("分组:", group)

打印结果:

分组: ['组员3', '组员4', '组员6', '组员0', '组长']

分组: ['组员1', '组员5', '组员3', '组员4', '组员6']

分组: ['组员2', '组员1', '组员5', '组员3', '组员4']

分组: ['组员0', '组长', '组员2', '组员1', '组员5']

分组: ['组员6', '组员0', '组长', '组员2', '组长']

Process finished with exit code 0

如果你有更好的方法,欢迎评论留言~

#End#

python随机分组的思路_一个关于随机分组需求的Python方案与思考相关推荐

  1. python数据建模案例源代码_一个完整的数据分析案例 | 用Python建立客户流失预测模型(含源数据+代码)...

    原标题:一个完整的数据分析案例 | 用Python建立客户流失预测模型(含源数据+代码) 来源:数据分析不是个事儿 作者:启方 原文: https://mp.weixin.qq.com/s/_20MN ...

  2. python爬虫接单经历_一个Python小白5个小时爬虫经历

    环境搭建 既然用python,那么自然少不了语言环境.于是乎到官网下载了3.5版本的.安装完之后,随机选择了一个编辑器叫PyCharm,话说python编辑器还真挺多的.由于本人是小白,所以安装事项不 ...

  3. python樱花树的设计思路_用python绘制樱花树

    黑夜可能漫长,但总会迎来温暖的阳光,三月如期而至,武大的樱花又一次盛开.那么今天就一起来看看怎样在python中画一棵美丽的樱花树- 说到用python画画,那当然就是小乌龟Turtle库了,为啥是t ...

  4. python随机种子的作用_简述pythonpytorch 随机种子的实现

    随机数广泛应用在科学研究, 但是计算机无法产生真正的随机数, 一般成为伪随机数. 它的产生过程: 给定一个随机种子(一个正整数), 根据随机算法和种子产生随机序列. 给定相同的随机种子, 计算机产生的 ...

  5. python开源的etl工具_一个开源的ETL工具Airflow

    Airflow 最近在弄画像标签每天 ETL 的调度事情, 这篇文章分享一下一个开源的 ETL 工具 Airflow . 一.基础概念 Airflow 是 Airbnb 内部发起并开源的一个 ETL ...

  6. python后端需要什么基础_一个六年经验的python后端是怎么学习用java写API的(6) 基本的Auth...

    描述 实现了依赖注入之后就可以方便的实现各种API的业务逻辑了,下一部的问题就在于权限,我们知道大部分的系统API并不是开放的,需要基本的用户体系(注册.登录.购买.会员.不同的role等等),例如管 ...

  7. python中面向对象的缺点_最简单的方法搞懂Python面向对象

    1.面向对象介绍 2.类和对象 3.面向对象基本语法 面向对象与面向过程面向过程:根据业务逻辑从上到下写代码. 面向对象:将变量与函数绑定到一起,分类进行封装,每个程序只要负责分配给自己的分类,这样能 ...

  8. python中digits什么意思_在Caffe中使用 DIGITS自定义Python层

    Caffe 使得我们有了使用Python自定义层的能力,而不是通常的C++/CUDA.这是一个非常有用的特性,但它的文档记录不足,难以正确实现本演练将向您展示如何使用DIGHT来学习实现Python层 ...

  9. python 数组合并排重_并排深度学习:Julia vs Python

    python 数组合并排重 Julia could possibly be the biggest threat to Python. For a variety of applications, J ...

  10. java使用队列实现栈思路_算法面试:队列实现栈的方案

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本篇介绍的是如何用两个队列实现栈的问题.这道题作为上一篇文章算法面试:栈实现队列 ...

最新文章

  1. python新手任务:python循环嵌套
  2. 如何彻底解决pip install慢的问题
  3. 程序员,技术的“背锅侠”,盘点 2020 年面向监狱编程的那些事!
  4. ORACLE ERP 的前世今生(5)
  5. LaTeX实战经验:数学公式环境注意事项
  6. 恒位油杯故障原因_抽油烟机常见故障及处理方法
  7. oracle flex cluster,【Ora12c-GI】将Standard集群修改为Flex集群
  8. MySQL的环境变量配置
  9. [Asp.net 开发系列之SignalR篇]专题五:SignalR支持的平台
  10. C++ 类的静态成员详细讲解(转)
  11. SSAS知识回放之订单数据分析
  12. 数据集的非均衡问题(imbalanced data)和应对方法
  13. 图片夹_【第8期】EHS大咖答疑解惑吊运事故的罪魁祸首之一:钢丝绳夹!不看不知道!...
  14. Arduino PS2手柄小车代码
  15. python星号直角三角形边长公式_直角三角形求边长公式图解
  16. c语言打印星号金字塔图形
  17. 想知道吗?CTO 比普通程序员强在哪?
  18. java8 Exception全集
  19. 手机APP抓包问题总结及相关解决方案
  20. java内存分析工具_java内存查看与分析

热门文章

  1. python 读取并显示图片的两种方法
  2. infer的用法_infer的用法总结大全
  3. 计算机round是什么函数,round()函数,excel round什么意思
  4. 计算机启动键,U启动U盘启动盘一键启动按键大全
  5. 美联储加息落地 题材股继续活跃创业板大涨1.85%
  6. c语言编程竞赛活动主题,第三届“希望之星”C语言编程大赛系列活动
  7. 国外服务器修改dns地址,怎样设置国外DNS国外DNS服务器域名解析方法.doc
  8. 记录一下matlab画雷达图
  9. win10计算机的数字小键盘,win10开启数字小键盘的方法(图文)
  10. mysql跨库oracle查询,Oracle跨数据库查询(databaselink方式)