比赛 组合问题
简述:已知有两支乒乓球队要进行比赛,每队各出三人;
甲队为a,b,c三人,乙队为x,y,z三人;
已抽签决定比赛名单。
问题:有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
li1 = ['a','b','c']
li2 = ['x','y','z']
# 全排列 有九种
allMatchs = [m+n for m in li1 for n in li2]
print(allMatchs)
['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
如果只是解决这个问题,肯定有简单点的办法,根据条件 a说他不和x比,c说他不和x,z比 去生成可能的结果
现在 我想找找看 '田忌赛马' 两两捉对厮杀的 共有多少种组合
先确定 结果的形式: [{'a':'x','b':'y','c':'z'},{...}...]
# 结果集合 操作的行 列索引
def nextProp(res,rIndex,cIndex,li1,li2):
v = li2[cIndex]
keys = []
##
for e in li1:
if not res[rIndex].get(e):
keys.append(e)
newRows = []
for kIndex in range(len(keys)):
if kIndex==0:
res[rIndex][keys[kIndex]] =v
continue
else:
newRow = res[rIndex].copy()
newRow.pop(keys[kIndex-1]) ## 把前面 kIndex==0 时候赋的值也copy过来了 去掉
newRow[keys[kIndex]] = v
newRows.append(newRow) ## 循环内部先使用新的list 不要影响循环
res+=newRows
def getAllOptions(li1,li2,res=None):
if not res: # 为空,第一次 初始化res
res = []
for e in li1:
row = {e:li2[0]}
res.append(row)
for cIndex in range(1,len(li2)):
for rIndex in range(len(res)):
nextProp(res,rIndex,cIndex,li1,li2) # 填下一个属性
return res
opts = getAllOptions(li1,li2)
for e in opts:
print(e)
{'a': 'x', 'b': 'y', 'c': 'z'}
{'b': 'x', 'a': 'y', 'c': 'z'}
{'c': 'x', 'a': 'y', 'b': 'z'}
{'a': 'x', 'c': 'y', 'b': 'z'}
{'b': 'x', 'c': 'y', 'a': 'z'}
{'c': 'x', 'b': 'y', 'a': 'z'}
a说他不和x比,c说他不和x,z比, 现在就可以据此排除了,将刷选条件写成 回调函数
def filterOptions(opts,*fns):
res = []
for e in opts:
flag = True
for fn in fns:
if not fn(e):
flag = False
break
if flag:
res.append(e) # 没有因为不符合条件break 到这里就可以加进结果集了
return res
def f1(e):
return e.get('a') !='x'
def f2(e):
return e.get('c')!='x' and e.get('c')!='z'
res = filterOptions(opts,f1,f2)
print(res)
[{'b': 'x', 'c': 'y', 'a': 'z'}]
python中对list dict中的查询遍历操作等全靠循环,一时间想不起来了....
到时新技能get:
arr = [2,45,50,24,35]
for i in arr:
if i>50:
break
else:
print('arr里没有比50大的数!')
arr里没有比50大的数!
for 和 else 类似于 if和else,当for里没有break的时候,就会进去else
for i in arr:
pass
else:
print('arr里没有比50大的数!')
arr里没有比50大的数!
for 里if不是关键, 关键看break, 有break没else,没break有else
可以在 for里用if exp :break 筛除, 剩下的进入else中处理
import math #
l = [2, 3]
for i in range(5, 101): #第一层循环,从5到100
for j in range(2, int(math.sqrt(i))+1): #一个数的最大因数是它的平方根
if i%j == 0: #如果出现整除说明有因子
break
else:
l.append(i) #for正常执行(包括contine)完会执行else,break不会执行else
print(" ".join(map(str, l))) #先将列表中的元素变为字符串再用空格连接输出
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97