2017-03-16 100 views
0

我們有一個使用itertools.combinations()的腳本,它似乎掛起的輸入大小很大。Python的超時問題itertools.combinations()

我是一個相對缺乏經驗的Python程序員,所以我不知道如何解決這個問題。有更合適的圖書館嗎?或者有沒有辦法啓用詳細日誌記錄,我可以調試爲什麼方法調用掛起?

任何幫助,非常感謝。

[編輯]

def findsubsets(S,m): 
    return set(itertools.combinations(S, m)) 

for s in AllSearchTerms: 
    S.append(itemsize) 
    itemsize = itemsize + 1 

for i in range (1,6): 
    Subset = findsubsets(S,i) 
    for sub in Subset: 
     for s in sub: 
      sublist.append(AllSearchTerms[s]) 
     PComb.append(sublist) 
     sublist = [] 
+5

'itertools.combinations(..)'本身是** lazy **。因此,它取決於**消費者對輸出**做了什麼...... –

+2

正如前面的評論所述,結果取決於你對來自'itertools.combinations()'的返回值做了什麼。如果您需要更多幫助,請向我們展示一個代碼片段,其中顯示您對結果和結果掛起的操作。請參見[如何創建最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)。 –

+0

此外,您的算法的組合數量[可能是_huge; _](https://en.wikipedia.org/wiki/Binomial_coefficient#Binomial_coefficients_as_polynomials)可能是正確的,只是工作時間超出您的預期。 – 9000

回答

0

你在你的代碼的兩件事情,將掛於大尺寸的輸入。

首先,您的函數findsubsets調用itertools.combinations然後將結果轉換爲集合。 itertools.combinations的結果是一個生成器,每次生成一個組合,而不存儲它們或一次全部計算它們。當你將它轉換爲一個集合時,你可以強制Python計算並一次存儲它們。因此,行return set(itertools.combinations(S, m))幾乎可以肯定你的程序掛起的地方。您可以通過在該行之前和之後立即放置打印語句(或其他類型的日誌語句)來檢查該情況,並且如果看到前面的打印並且程序在看到後續打印之前掛起,則會發現問題。解決方案不是將組合轉換爲集合。將其作爲生成器保存,並且您的程序可以根據需要一次抓取一個組合。第二,即使你按我剛剛建議的做法,你的循環for sub in Subset:是一個相當緊密的循環,它使用每一種組合。如果輸入規模很大,那麼這個循環將需要很長時間,並且執行我之前的段落也無濟於事。你可能應該重新組織你的程序以避免大的輸入大小,或者至少在循環中顯示某種進展。組合功能has a predictable output size,所以你甚至可以顯示進度條中完成的百分比。

itertools.combinations內部沒有記錄,因爲正確使用時不需要記錄,並且在將發生器轉換爲集合時沒有記錄。如果需要,您可以在自己的緊密循環中實現日誌記錄。

+0

Thanks @Rory。是的,你是完全正確的 - 我已經把日誌聲明,並可以確認'返回集(itertools.combinations(S,m))'是它掛起的地方。我會嘗試你的建議解決方案,看看它是否解決了這個問題。我會測試這個和upvote如果它的作品:) –