我正在尋找一種實作遞回函式的方法,以在不使用 itertools 包的情況下獲得 n 次相同串列的通用笛卡爾積。該函式應該將串列和 n 次作為引數獲取。
輸出示例:
>>> l = [0, 2]
>>> print([(x,y) for x in l for y in l])
>>> [(0, 0), (0, 2), (2, 0), (2, 2)]
但是也:
>>> l = [0,2]
>>> print([(x,y,z) for x in l for y in l for z in l])
>>> [(0, 0, 0),(0, 0, 2),(0, 2, 0),(0, 2, 2),(2, 0, 0),(2, 0, 2),(2, 2, 0),(2, 2, 2)]
或者
>>> l = [4,5,8]
>>> print([(x,y) for x in l for y in l])
>>> [(4, 4), (4, 5), (4, 8), (5, 4), (5, 5), (5, 8), (8, 4), (8, 5), (8, 8)]
等等..
我想對每個通用串列和每個 n 元組進行概括。我找到了不同的方法來迭代地實作這一點,但沒有使用遞回。希望任何人都可以幫助我。
uj5u.com熱心網友回復:
試試這個
def cartesian_product(lst, n):
if n == 1:
return [(x,) for x in lst]
return [(x,) t for t in cartesian_product(lst, n - 1) for x in lst]
uj5u.com熱心網友回復:
直覺的
比使用固定整數更好,我認為product(t)應該采用可迭代串列 -
- 如果輸入
t為空,則產生空產品,() - (inductive)
t至少有一個可迭代物件。對于所有p在子問題的結果product(t[1:]),對于所有v在第一迭代t[0],前置v到p和產量
def product(t):
if not t:
yield () # 1. no iterables
else:
for p in product(t[1:]): # 2. at least one iterable
for v in t[0]:
yield (v, *p)
我將輸入乘以*2你仍然可以控制輸出product-
for p in product([[1,2]] * 2):
print(p)
(1, 1)
(2, 1)
(1, 2)
(2, 2)
現在讓我們乘以*3-
for p in product([[1,2]] * 3):
print(p)
(1, 1, 1)
(2, 1, 1)
(1, 2, 1)
(2, 2, 1)
(1, 1, 2)
(2, 1, 2)
(1, 2, 2)
(2, 2, 2)
靈活的
由于可以使用任何迭代,您可以根據自己的喜好混合/匹配 -
for p in product([range(2), [3,4], "hi", (9,)]):
print(p)
(0, 3, 'h', 9)
(1, 3, 'h', 9)
(0, 4, 'h', 9)
(1, 4, 'h', 9)
(0, 3, 'i', 9)
(1, 3, 'i', 9)
(0, 4, 'i', 9)
(1, 4, 'i', 9)
高效的
使用生成器可以product有效地處理涉及組合學的問題。生成器允許我們在找到所需結果后暫停/取消并提早退出 -
def solveTriangle(min, max):
for (x,y,z) in product([list(range(min, max))] * 3):
if x ** 2 y ** 2 == z ** 2:
return (x,y,z) # <- return stops generator
return None
print(solveTriangle(10,30))
(16, 12, 20)
迭代工具
請注意,該itertools模塊將產品作為內置功能提供。product作為練習來實作很有趣,但如果您打算在生產代碼中使用它,內置函式可能會提供最佳性能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/384448.html
上一篇:是否可以在球拍中創建匿名遞回函式
下一篇:遞回冪集函式的時間復雜度
