[英]avoid computing whole cartesian product (python itertools)
我的目標是找到nxn矩陣(2 <= n <= 15)中對角線的任何排列。 矩陣由零和一組成。
目前我是這樣的:
indices = [[j for j, x in enumerate(row) if x == 1]
for row in self.matrix]
cart = list(itertools.product(*indices))
cart = [list(tup) for tup in cart]
cart = filter(lambda dia: len(list(set(dia))) == len(dia), cart)
return cart
如果矩陣不是太大,則可以正常工作,否則將失敗並顯示:MemoryError
那么有沒有辦法避免購物車的整個計算呢? 這樣,例如找到一個排列,計算就停止了嗎?
只需不對itertools.product
的結果調用list
並使用itertools.ifilter
代替filter
使所有評估變得懶惰:
from itertools import ifilter, product
indices = [[j for j, x in enumerate(row) if x == 1] for row in self.matrix]
cart = product(*indices)
found_cart = next(ifilter(lambda dia: len(set(dia)) == len(dia), cart), None)
next
返回第一種情況,即ifilter
中的謂詞為True
或在沒有匹配項的情況下返回None
。
找到匹配項后, 計算將停止。
您可以簡化代碼的最后一部分,使其僅返回第一個答案:
def foo(matrix):
indices = [[j for j, x in enumerate(row) if x == 1] for row in matrix]
# this part is changed, very simple and efficient now
for dia in itertools.product(*indices):
if len(set(dia)) == len(dia):
return dia
換句話說,不要對filter
和lambda以及其他所有內容都那么聰明-這是不必要的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.