在看 code 時又看到一段神奇的程式碼。有骰子大法的味道。
程式碼目標是隨機選出不重複的 A,B,C,其中 A 從 1 ~ N。這裡可以發現其實 A 不是隨機,所以不應該讓它也從 sample 得到。原程式碼的方法是隨機 sample 三個數字,看 A 有沒有在 sample 到的數字裡,沒有的話再重新骰一遍。另外上下文查看了一下 sort 似乎沒必要,所以就來修改了。
原始程式碼:
N = 10
for A in range(N):
selected = []
while A not in selected:
selected = random.sample(range(N), 3)
selected.sort()
if selected.index(A) == 0:
B = selected[1]
C = selected[2]
elif selected.index(A) == 1:
B = selected[0]
C = selected[2]
elif selected.index(A) == 2:
B = selected[0]
C = selected[1]
print(A, B, C)
這邊最主要的觀念應該是要如何避免 sample 到重複的 A,很簡單: 一開始把 A 拿掉再 sample 就好。修改後要排序也可以,B, C = selected
改成 B, C = sorted(selected)
即可。簡潔又沒有骰不到的問題。要更簡短的話可以 B, C = random.sample(...)
。
根據語義調整:
for A in range(N):
selected = random.sample([i for i in range(N) if i != A], 2)
B, C = selected
print(A, B, C)
完整程式碼
import random
random.seed(0)
N = 10
for A in range(N):
selected = []
while A not in selected:
selected = random.sample(range(N), 3)
selected.sort()
if selected.index(A) == 0:
B = selected[1]
C = selected[2]
elif selected.index(A) == 1:
B = selected[0]
C = selected[2]
elif selected.index(A) == 2:
B = selected[0]
C = selected[1]
print(A, B, C)
print("---")
for A in range(N):
selected = random.sample([i for i in range(N) if i != A], 2)
B, C = sorted(selected)
print(A, B, C)
python test.py
0 6 9
1 2 4
2 4 9
3 7 9
4 7 8
5 7 9
6 1 7
7 0 4
8 4 6
9 3 8
---
0 7 5
1 8 9
2 6 1
3 6 1
4 8 6
5 3 9
6 0 4
7 1 3
8 5 2
9 5 6