該程式的目標是進行盡可能多的x
大小排列3
( nPr(5,3)
,因此迭代(i, j, k)
)。
我試圖實作排列的努力,串列的長度在哪里nPr(5,3)
,元組的長度在哪里:5
x
3
(i,j,k)
# x will never have any repeats
x = [1, 2, 3, 4, 5]
# nPr(5,3) = 60
y = []
for i in x:
for j in x:
for k in x:
y.append((i, j, k))
print(f"Len of y = {len(y)}")
我預計len(y)
60歲,因為nPr(5,3) = 60
。但我得到了輸出Len of y = 125
。此外,制作y = set()
并不能解決此問題
- 我做錯了什么?
- 如何修復此代碼以使其正常作業(不使用
itertools
)
回答TL;DR:我允許重復(1,1,1)
uj5u.com熱心網友回復:
您允許重復(例如,[1,1,1] 和 [2,2,2])。60 的值用于沒有重復的排列。你通過檢查你沒有重復一個值來做到這一點。
請注意,此代碼僅在x
. 如果有重復項,那么您將不得不使用索引(即for i in range(len(x)):
)。
x = [1,2,3,4,5]
y = []
for i in x:
for j in x:
if i == j:
continue
for k in x:
if i!=k and j!= k:
y.append((i,j,k))
print(y)
uj5u.com熱心網友回復:
正如蒂姆·羅伯茨(Tim Roberts)所指出的,我添加了i,j or k
,的重復(1,1,1)
。我的解決方法是確保i,j and k
它們不同:
for i in x:
for j in x:
for k in x:
# If i,j,k are different
if len(set((i, j, k))) == 3:
y.append((i, j, k))
Asset((i, j, k))
將洗掉 tuple 中的重復項(i, j, k)
,因此長度必須等于 3。如果我需要對nPr(n,r)
as進行遞回,這也很有幫助set((i, j, k ... r)) == r
。
uj5u.com熱心網友回復:
這將起作用,盡管它對我的口味來說嵌套太深了:
y = []
for i in x:
for j in x:
if i != j:
for k in x:
if i != k and j != k:
y.append((i, j, k))
assert list(itertools.permutations(x, 3)) == y
否定條件并使用continue
增加可讀性:
y = []
for i in x:
for j in x:
if i == j:
continue
for k in x:
if i == k or j == k:
continue
y.append((i, j, k))
assert list(itertools.permutations(x, 3)) == y
但這只有在所有成員x
都是唯一的情況下才有效。最好檢查索引是否不同:
y = []
for i in range(len(x)):
for j in range(len(x)):
if i == j:
continue
for k in range(len(x)):
if i == k or j == k:
continue
y.append((x[i], x[j], x[k]))
assert list(itertools.permutations(x, 3)) == y
我們還可以在程序中使用遞回、引數化r
(每個排列中的專案數)來完成這項作業,盡管沒有動態編程x
,這種方法會為大的和做很多額外的作業r
:
# if x were hashable, i.e. a tuple in this case, we could use the
# @functools.cache decorator to avoid repeated work
def permutations(x, r):
if not r:
return [(),]
res = []
for i in range(len(x)):
perms_without_x_i = permutations(x[:i] x[i 1 :], r - 1)
res = [(x[i],) p for p in perms_without_x_i]
return res
assert permutations(x, 3) == list(itertools.permutations(x, 3))
但可能最好的方法是直接從檔案中竊取答案:
def permutations(iterable, r=None):
# permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i 1:] indices[i:i 1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/438688.html
標籤:Python python-3.x 排列