一、问题
1. 将20位同学随机分成五组,每组4人
2. 且20位同学中有三位不会Python,不能分在同组
3. 且20位同学中有8位女生,每组要求至少1名女生
二、解决
1. 随机排序问题
1) 应用random包产生一组1~20的随机数,对应元素在list中的顺序

import random
rank = random.sample(range(1,21),20)
name = ["zhao","qian","sun","li","zhou","wu","zheng","wang","feng","chen","chu","wei","jiang","shen","han","yang","zhu","qin","you","xu"]
group1 = []
group2 = []
group3 = []
group4 = []
group5 = []
group = [group1, group2, group3, group4, group5]
for m in range(0,5):		#对不同的组进行操作
    for n in range(1,5):	#添加每个组内的组员
        group[m].append(name[rank.index(n+m*4)])
for i in range(1,6):		#打印每个组的组员
    print("The students in group "+str(i)+" are "+str(group[i-1]))

这种方法是一种不用排序的排序算法。
2) 应用random包的shuffle函数直接排序

from random import shuffle
name = ["zhao","qian","sun","li","zhou","wu","zheng","wang","feng","chen","chu","wei","jiang","shen","han","yang","zhu","qin","you","xu"]
shuffle(name)
#以下步骤同上,略
  1. 三位不会的单独分组
from random import shuffle
name = ["zhao","qian","sun","li","zhou","wu","zheng","wang","feng","chen","chu","wei","jiang","shen","han","yang","zhu","qin","you","xu"]
shuffle(name)

group1 = []
group2 = []
group3 = []
group4 = []
group5 = []
group = [group1, group2, group3, group4, group5]
for m in range(0,5):
    for n in range(0,3):
        group[m].append(name[n+m*3])	#先把name列表中的前十五个分到五组
group1.append(name[-1])			#把name列表的最后两个人分到第1、2组
group2.append(name[-2])
group3.append("CannotPY1")		#最后把不会python的三位同学分到3、4、5组
group4.append("CannotPY2")
group5.append("CannotPY3")
for i in range(1,6):
    print("The students in group "+str(i)+" are "+str(group[i-1]))
  1. 先给每组分配一位会python的女生,剩下的会python的女生和会python的男生合并分配至不同组,最后分配不会python的
from random import shuffle
GirlCanPY = ["zzhao","qqian","ssun","lli","zzhou","wwu","zzheng","wwang"]
RestCanPY = ["feng","chen","chu","wei","jiang","shen","han","yang","zhu","qin","you","xu"]
CannotPY = ["CannotPY1","CannotPY2","CannotPY3"]
shuffle(GirlCanPY)
group1 = []
group2 = []
group3 = []
group4 = []
group5 = []
group = [group1, group2, group3, group4, group5]
for m in range(0,5):
    group[m].append(GirlCanPY[0])	#取会python的前五个女生分配到1-5组
    del GirlCanPY[0]			#取完则删除,一是为了下一组继续取,二是为了之后将没取过的合并到RestCanPY
for x in GirlCanPY:
    RestCanPY.append(x)			#合并所有的能用python的男女生
shuffle(RestCanPY)
for m in range(0,5):
    for n in range(0,2):
        group[m].append(RestCanPY[n+m*2])#随机后将会python的人分配到5组
group1.append(RestCanPY[-1]) 		#分配还没分配过的
group2.append(RestCanPY[-2])
group3.append(CannotPY[0]) 		#分配不会python的
group4.append(CannotPY[1])
group5.append(CannotPY[2])
for i in range(1,6):
    print("The students in group "+str(i)+" are "+str(group[i-1]))
  1. (更新)问题模型最终确定为:
    条件:班里共20位同学,其中不会Python有3人,本专业会Python男女各六人,外专业会Python5人且均为男生。
    要求:每组最多一个不会编程的,最少一个女生,且有一个外专业的。
    新代码的改变处进行了注释如下:
from random import shuffle

#把非本专业但会用Python的单独分离为OthersCanPY
OthersCanPY = ["ocp1","ocp2","ocp3","ocp4","ocp5"]
GirlCanPY = ["gcp1","gcp2","gcp3","gcp4","gcp5","gcp6"]
RestCanPY = ["rcp1","rcp2","rcp3","rcp4","rcp5","rcp6"]
CannotPY = ["cnp1","cnp2","cnp3"]
group1 = []
group2 = []
group3 = []
group4 = []
group5 = []
group = [group1, group2, group3, group4, group5]

#把每个数组都随机排序,保证随机性
shuffle(GirlCanPY)
shuffle(OthersCanPY)
shuffle(RestCanPY)
shuffle(CannotPY)

#这里其实有个默认前提,就是GirlCanPY与OthersCanPY的人数都大于5
for m in range(0,5):
    group[m].append(GirlCanPY[0])
    del GirlCanPY[0]
for m in range(0,5):
    group[m].append(OthersCanPY[0])
    del OthersCanPY[0]

#把分配一轮过后剩下的人都加入RestCanPY,乱序后入组
for x in GirlCanPY: 
    RestCanPY.append(x)
for x in OthersCanPY:
    RestCanPY.append(x)
shuffle(RestCanPY)
for m in range(0,5):
    for n in range(0,1):
        group[m].append(RestCanPY[n+m*1])

#把5组随机排序,目的是保证CannotPY入组随机性
shuffle(group)
group[0].append(RestCanPY[-1])
group[1].append(RestCanPY[-2])
group[2].append(CannotPY[0])
group[3].append(CannotPY[1])
group[4].append(CannotPY[2])

for i in range(1,6):
    print("The students in group "+str(i)+" are "+str(group[i-1]))

三、反思

  1. 随机性:进行随机分组时,除了可以将内部元素进行shuffle,再加入小组,还可以先把小组shuffle再顺序添加元素,实际也是随机。但是一个没有解决的问题是,为什么实际执行代码时,不会PY的三个人必定分到group3,4,5
  2. 可移植性:一个问题是,如果GirlCanPY和OthersCanPY的人数小于5,分组规则可能也会变化,情况更加复杂,代码需要调整;同时需要解决某特定类人的集合内元素数小于组数时,如何才能将这些人随机分配到各个组,而非比如必定分到group3,4,5的情况