अजगर: अधिकतम पुनरावृत्ति गहराई पार हो गई


85

मेरे पास निम्न पुनरावर्तन कोड है, प्रत्येक नोड पर मैं मूल नोड से संबंधित नोड प्राप्त करने के लिए 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

विधि जिसे मैं sql परिणाम प्राप्त करने के लिए कहता हूं:

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();

मैं वास्तव में उपरोक्त विधि के साथ कोई समस्या नहीं है, लेकिन मैं इस सवाल का उचित अवलोकन देने के लिए वैसे भी डाल दिया।

पुनरावर्तन कोड:

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

यदि पुनरावृत्ति बहुत गहरी है, तो मुझे अपने पुनरावृत्ति फ़ंक्शन को कॉल करने पर त्रुटि हो रही है, लेकिन जब मैं शब्दकोश प्रिंट करता हूं तो मुझे यह त्रुटि मिलती है।


8
पुनरावृत्ति के बजाय पुनरावृति से इसे पुन: लिखें।
सेठ कार्नेगी

1
if first:चेक के साथ अनावश्यक है for elem in first:। यदि क्वेरी एक रिक्त परिणाम सूची लौटाती है, तो इस पर ध्यान देना, आपकी इच्छा के अनुसार, सही ढंग से कुछ भी नहीं करेगा। इसके अलावा, आप उस सूची को सूची बोध के साथ और अधिक बना सकते हैं (और वे अर्धविराम अनावश्यक हैं और आमतौर पर बदसूरत
माने जाते हैं

@KarlKnechtel अर्धविराम के बारे में क्षमा करें, क्या आप बता सकते हैं कि मैं सिर्फ पायथन प्रोग्रामिंग में शामिल हो रहा हूँ .... :)
ऐड-सेमी-कॉलन

माफी मांगने की जरूरत नहीं है, मैं आपको इसे लिखने के लिए भुगतान नहीं कर रहा हूं :) मुझे उम्मीद है कि आप पायथन को मुक्त कर पाएंगे;)
कार्ल केनचेल

जवाबों:


162

आप अनुमति दी गई ढेर की गहराई को बढ़ा सकते हैं - इसके साथ, इस तरह की गहरी पुनरावर्ती कॉल संभव होगी:

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

... लेकिन मैं आपको सलाह दूंगा कि पहले आप अपने कोड को पुन: अनुकूलन करने के बजाय पुनरावृति का उपयोग करके अपने कोड को अनुकूलित करने का प्रयास करें।


1
मैंने १०००० की बजाय लाइन जोड़ी, मैंने ३०००० जोड़ा, लेकिन मैंने सेगमेंटेशन फ़ॉल्ट (कोर डंप किया गया) को समाप्त कर दिया :(
ऐड-सेमी-कॉलन नोव

16
वहाँ एक कारण है कि यह 1000 पर सेट है ... मेरा मानना ​​है कि गुइडो वैन रोसुम ने इस बारे में कुछ कहा
लैम्ब्डा फेयरी

3
तो गुइडो का तर्क यह है कि उचित टेल कॉलिंग (1) बदतर स्टैक निशान प्रदान करता है --- जैसा कि आप इसे पुनरावृत्त लिखते समय किसी भी फ्रेम के विपरीत नहीं हैं? यह कितना बुरा है? (२) यदि हम उन्हें कुछ अच्छा देते हैं, तो वे उस पर निर्भर होना शुरू कर सकते हैं। (३) मुझे इस पर विश्वास नहीं है, इसमें स्कीम जैसी खुशबू आ रही है। (4) पायथन बुरी तरह से डिज़ाइन किया गया है, ताकि एक कंपाइलर कुशलता से यह पता न लगा सके कि क्या कोई पूंछ कॉल है। मुझे लगता है कि हम जिस पर सहमत हो सकते हैं?
जॉन कुलीज

1
@ हेजफ थर्ड, टेल-कॉलिंग केवल सूचियों के लिए नहीं है; किसी भी पेड़ की संरचना जीत जाती है। लूप में पुनरावर्ती कॉल के बिना एक पेड़ का पता लगाने की कोशिश करें; आप हाथ से स्टैक मॉडलिंग मॉडलिंग करते हैं। अंत में, आपके तर्क कि पायथन को इस तरह से डिज़ाइन नहीं किया गया था, निश्चित रूप से सच है, लेकिन मुझे यह समझाने के लिए बहुत कम है कि यह एक ईश्वर का डिज़ाइन है।
जॉन क्लेमेंट्स

1
सिर्फ इसलिए कि वैन रोसुम ने अपने बोनट में एक मधुमक्खी को पुनरावृत्ति के बारे में बताया है कि पुनरावृत्ति के बजाय पुनरावृत्ति "इष्टतम" नहीं है: इस बात पर निर्भर करता है कि आप क्या अनुकूलन कर रहे हैं!
जीन Callahan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.