比賽 組合問題
簡述:已知有兩支乒乓球隊要進行比賽,每隊各出三人;
甲隊為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