2017-08-02 100 views
-2

我有一個簡單的腳本使用GyPython組件Rhino/Grasshopper。目標是將小時天氣數據(只記錄幾小時)分配到幾小時。如果沒有測量返回0。它應該這樣工作(例如具有類似的值):大型數據集崩潰python腳本

hoursList = [hr1,hr2,hr3,hr4,hr5,hr6] 
measuredList = [hr2,hr3,hr6] 
recordList = [wData1,wData2,wData3] 
finalList = []  

def assignData(i,y):   
    for i < len(leadList):    
     if hoursList[i] == measuredList[y]:     
      finalList.append(recordList[y])     
      i += 1 
      y += 1     
     else:     
      finalList.append(0)     
      i += 1  
     assignData(i,y)  

i = 0 
y = 0  
assignData(i,y) 

其中應該返回

[0,wData1,wData2,0,0,wData3] 

的用於這種情況下得到的finalList(換行符加入幫助可讀性)

[0, 'wData1', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData1', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3'] 

當我嘗試運行大型數據列表(約43000個值)的代碼,之後崩潰大約7000次迭代。我檢查了sys.getrecursionlimit,它是2147483647.任何想法如何獲得這項工作?

+0

歡迎來到StackOverflow。請閱讀並遵守幫助文檔中的發佈準則。 [最小,完整,可驗證的示例](http://stackoverflow.com/help/mcve)適用於此處。在發佈您的MCVE代碼並準確描述問題之前,我們無法爲您提供有效的幫助。 我們應該能夠將發佈的代碼粘貼到文本文件中,並重現您描述的問題。 尤其是,你還沒有給我們leadList' - 更好的是,只需從給定的變量中得出它的長度,所以我們可以運行你的代碼。 – Prune

+0

另外,請注意,您的代碼不起作用。你有語法錯誤可以阻止它運行,更不用說你描述的方式了。它不*返回*任何東西;相反,它改變了全球名單作爲一個副作用,你沒有打擾向我們展示。 – Prune

+0

除此之外,你實際得到的6個元素數據集的輸出是什麼?我可以在我的例子中看到它,但這應該是*你的問題來描述。 – Prune

回答

2

分析

我推測,len(leadList)是43000數字你給。我會打電話給limit

注意你的循環是如何工作的:在範圍內的i每一個值「輸入I」到limit,這個處理一個項目,增量i(也許y),和復發。因此,您在i=0的頂級呼叫將產生一個致電assignData(1, 0)(假設失敗)的呼叫並等待完成。然後它將回到循環的頂部,與i = 1一起工作,然後繼續......最終產生limit遞歸調用。

該初始呼叫現在將工作範圍(1,限制),產卵limit-1調用,其中第一個將產生limit-2調用,等等。每個級別都會產生一個大扇出的另一個級別。

簡而言之,你產生的呼叫比我想象的要多得多;隨着您增加limit,總增長相當快。

我懷疑你的問題是finalList只是超過了可用內存,因爲每個調用都附加了一個元素。

調查

插入基本調試語句轉換成代碼:

def assignData(i, y): 
    print "ENTER", i, y, finalList 
    for i < len(leadList): 
     ... 

所以,你可以看到通話的進展。

REPAIR

我懷疑你需要這個雙重嵌套的遞歸棧。事實上,我沒有看到遞歸向你購買任何東西。看起來你只需要遍歷列表一次,找到實際對應的時間,否則填充0。擺脫呼叫,正確使用for來控制i的值,並根據需要減少代碼。

def assignData(): 
    y = 0   
    for i in range(0, len(leadList)):    
     if hoursList[i] == measuredList[y]:     
      finalList.append(recordList[y])     
      y += 1     
     else:     
      finalList.append(0) 

更好的解決方案

如果你需要的是匹配次的記錄,可以讓這個更直接。建立一個詞典來索引時間的測量值。

meas = dict(zip(measuredList, recordList) 

現在,寫一個列表理解爲任何時候都不要在字典中插入0。

finalList = [meas[time] if time in meas else 0 
       for time in hourslist] 

如果我正確地閱讀您的問題,那是您的總體目標。