2011-11-18 172 views
69

我有以下遞歸代碼,在每個節點我調用sql查詢來獲取節點屬於父節點。Python:超過最大遞歸深度

這裏是錯誤:

def returnCategoryQuery(query, variables={}): 
    cursor = db.cursor(cursors.DictCursor); 
    catResults = []; 
    try: 
     cursor.execute(query, variables); 
     for categoryRow in cursor.fetchall(): 
      catResults.append(categoryRow['cl_to']); 
     return catResults; 
    except Exception, e: 
     traceback.print_exc(); 

我居然沒有上述方法的任何問題,但我把它給反正:

,我打電話讓SQL結果
Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method DictCursor.__del__ of <MySQLdb.cursors.DictCursor object at 0x879768c>> ignored 

RuntimeError: maximum recursion depth exceeded while calling a Python object 
Exception AttributeError: "'DictCursor' object has no attribute 'connection'" in <bound method DictCursor.__del__ of <MySQLdb.cursors.DictCursor object at 0x879776c>> ignored 

方法給出適當的問題概述。

遞歸代碼:

def leaves(first, path=[]): 
    if first: 
     for elem in first: 
      if elem.lower() != 'someString'.lower(): 
       if elem not in path: 
        queryVariable = {'title': elem} 
        for sublist in leaves(returnCategoryQuery(categoryQuery, variables=queryVariable)): 
         path.append(sublist) 
         yield sublist 
        yield elem 

調用遞歸函數

for key, value in idTitleDictionary.iteritems(): 
    for startCategory in value[0]: 
     print startCategory + " ==== Start Category"; 
     categoryResults = []; 
     try: 
      categoryRow = ""; 
      baseCategoryTree[startCategory] = []; 
      #print categoryQuery % {'title': startCategory}; 
      cursor.execute(categoryQuery, {'title': startCategory}); 
      done = False; 
      while not done: 
       categoryRow = cursor.fetchone(); 
       if not categoryRow: 
        done = True; 
        continue; 
       rowValue = categoryRow['cl_to']; 
       categoryResults.append(rowValue); 
     except Exception, e: 
      traceback.print_exc(); 
     try: 
      print "Printing depth " + str(depth); 
      baseCategoryTree[startCategory].append(leaves(categoryResults)) 
     except Exception, e: 
      traceback.print_exc(); 

代碼打印的字典,

print "---Printing-------" 
for key, value in baseCategoryTree.iteritems(): 
    print key, 
    for elem in value[0]: 
     print elem + ','; 
    raw_input("Press Enter to continue...") 
    print 

如果遞歸太深,我應該得到的錯誤當我調用遞歸函數時,但是當我打印字典時出現此錯誤。

+7

迭代而不是遞歸地重寫它。 –

+1

'首先:'檢查對於elem來說是多餘的:'。如果查詢返回一個空的結果列表,那麼迭代它將簡單地,正確地做任何事情,如你所願。此外,你可以創建列表更簡單的清單理解(和那些分號是不必要的,通常被認爲是醜陋:)) –

+0

@KarlKnechtel對不起,關於分號,你能告訴我只是進入Python編程.... :) –

回答

139

您可以增加允許的堆棧深度 - 這一點,更深層次的遞歸調用將成爲可能,這樣的:

import sys 
sys.setrecursionlimit(10000) # 10000 is an example, try with different values 

...但我建議你先嚐試優化你的代碼,實例,使用迭代而不是遞歸。

+0

我得到錯誤,當我嘗試打印,如果遞歸太深我應該得到錯誤當我調用遞歸函數時。因爲下線我調用這個函數,並將結果保存在字典中,當我嘗試打印字典時,我得到這個錯誤。我已經更新了代碼。 –

+0

我添加了行而不是10000我添加了30000,但我結束了分段錯誤(核心轉儲):( –

+4

嘗試一個較小的數字,然後 –