2012-04-02 17 views
6

मुझे लगता है कि एक ही कक्षाअजगर Recursion वस्तुओं और बच्चे वस्तुओं, प्रिंट बच्चे गहराई संख्या

class BoxItem: 
    def __init__(self, name, **kw): 
     self.name = name 
     self.boxItems = [] 
     ... #more attributes here 

box1 = BoxItem('Normal Box') 
box2 = BoxItem('Friendly Box') 
box3 = BoxItem('Cool Box') 
box4 = BoxItem('Big Box', [box1, box2]) #contains some children 
example = BoxItem('Example Box', [box4,box3]) #contains another level of children 

की वस्तुओं हमारे 'उदाहरण' बॉक्स वस्तु के साथ कार्य करना की एक सूची शामिल कर सकते हैं एक विशेषता के साथ एक सरल वर्ग है के माध्यम से, मैं हर संभव बॉक्स बच्चों यह हो सकता है की गहराई के माध्यम से छल, और वस्तुओं इतना प्रकार फ़ॉर्मेट प्रिंट आउट करना चाहते हैं:

1 Example Box 
1.1 Big Box 
    1.1.1 Normal Box 
    1.1.2 Friendly Box 
1.2 Cool Box 

के बीच की जरूरत नहीं है Tabbing, बस स्पष्ट रूप से पेड़ प्रारूप को दिखाने के लिए चाहते हैं। मैं ऑब्जेक्ट्स को नीचे चलाकर अपने खिताब प्रिंट करने में सक्षम हूं, लेकिन मैं माता-पिता/बाल संबंध दिखाने वाले सामने वाले नंबरों को प्रिंट करने में सक्षम नहीं हूं। (1, 1.1, 1.2 ...)

आपकी मदद :)

संपादित करें के लिए अग्रिम धन्यवाद यहाँ मैं अब तक

def print_boxes(box_list): 
    node_count = 0 
    for box in box_list: 
    node_count += 1 
    print str(node_count)+' '+box.name #prints out the root box 
    recursive_search(box,node_count) 

def recursive_search(box,node_count): #recursive automatically 
    level = 0 
    for child in box.boxItems: 
    level += 1 
    for x in range(len(child.boxItems)): 
     print x+1 #this prints out some proper numbers 
    print "level: "+str(level) #experiment with level 
    print child.name #prints out child box name 
    recursive_search(child,node_count) #runs the function again inside the function 

उत्तर

7

मुझे लगता है कि यह आपके लिए अधिक उपयोगी हो सकता है यदि मैं ऐसा करने का एक उदाहरण उदाहरण पोस्ट करता हूं, जहां आप कोड को समस्याएं कहां से गुज़रने के विरोध में हैं। हम इस तरह से बहुत तेज़ी से समझने के बिंदु पर पहुंच सकते हैं। आपके कोड में सही विचार है कि इसे गहराई को ट्रैक करने की आवश्यकता है। लेकिन एकमात्र चीज जो गायब है वह घोंसला वाली गहराई (पेड़) की भावना है। यह केवल पिछले node_count जानता है, और उसके बाद वर्तमान बाल गणना।

मेरा उदाहरण गहराई ट्रैकिंग ऑब्जेक्ट शुरू करने के लिए बंद करने का उपयोग करता है, और उसके बाद रिकर्सिव भाग करने के लिए एक आंतरिक फ़ंक्शन बनाता है। अपने उदाहरण से

def recurse(box): 

    boxes = not isinstance(box, (list, tuple)) and [box] or box 

    depth = [1] 

    def wrapped(box): 

     depthStr = '.'.join([str(i) for i in depth]) 
     print "%s %s" % (depthStr, box.name) 

     depth.append(1) 
     for child in box.boxItems: 
      wrapped(child) 
      depth[-1] += 1 
     depth.pop() 

    for box in boxes: 
     wrapped(box) 
     depth[0] += 1 

नमूना उत्पादन:

>>> recurse(example) 
1 Example Box 
1.1 Big Box 
1.1.1 Normal Box 
1.1.2 Friendly Box 
1.2 Cool Box 

>>> recurse([example, example]) 
1 Example Box 
1.1 Big Box 
1.1.1 Normal Box 
1.1.2 Friendly Box 
1.2 Cool Box 
2 Example Box 
2.1 Big Box 
2.1.1 Normal Box 
2.1.2 Friendly Box 
2.2 Cool Box 

इस विश्लेषण करना:

हम पहले एक बॉक्स तर्क स्वीकार करते हैं, और स्वचालित रूप से एक सूची के लिए स्थानीय स्तर पर परिवर्तित, यदि आप केवल था एक बॉक्स बॉक्स में पारित किया गया। इस तरह आप या तो एक बॉक्स ऑब्जेक्ट्स, या उनमें से एक सूची/टुपल पास कर सकते हैं।

depth हमारे गहराई ट्रैकर है। यह चींटियों की एक सूची है जिसे हम निर्माण और संक्षेप में घुमाएंगे क्योंकि रिकर्सन होता है। यह पहली वस्तु/प्रथम स्तर के लिए 1 से शुरू होता है। समय के साथ यह इस तरह दिख सकता है: [1,1,2,3,1] इस पर निर्भर करता है कि यह कितना गहरा है। यह मेरे कोड और आपके के बीच बड़ा अंतर है। प्रत्येक पुनरावर्तन के पास इस राज्य तक पहुंच है।

अब हमारे पास यह आंतरिक wrapped फ़ंक्शन है। यह एक मौजूदा बॉक्स आइटम लेने और इसे प्रिंट करने जा रहा है, और फिर अपने बच्चों पर फिर से शुरू होगा।हमें वर्तमान गहराई सूची में शामिल होने और फिर नाम से जुड़कर हमारी प्रिंट स्ट्रिंग मिलती है।

हर बार जब हम एक बाल सूची में उतरते हैं, तो हम अपनी गहराई सूची में एक प्रारंभिक स्तर 1 जोड़ते हैं, और जब हम उस बच्चे के लूप से बाहर आते हैं, तो हम इसे फिर से बंद कर देते हैं। उस लूप में हर बच्चे के लिए, हम उस अंतिम आइटम को बढ़ाते हैं।

उस wrapped आंतरिक कार्य के बाहर, फिर हम wrapped पर कॉल करके और हमारे पहले स्तर को बढ़ाने के बाद, हमारे प्रारंभिक बॉक्स पर लूप करके पूरी चीज शुरू करते हैं।

आंतरिक लपेटा हुआ कार्य एक बंद में गहराई की सूची का उपयोग करता है। मैं शर्त लगाने के लिए तैयार हूं कि अन्य इस पर कुछ और सुधार कर सकते हैं, लेकिन इसके उदाहरण के लिए मैं क्या आया।

समारोह

हम भी recurse डिज़ाइन कर सकता बजाय एक चर लंबाई तर्क सूची लेने के लिए, के बजाय एक सूची के लिए जाँच की के लिए आर्ग के बारे में नोट। यह इस प्रकार दिखाई देगा (और है कि पहले boxes = जांच से छुटकारा पाने के हैं):

def recurse(*boxes): 
    #boxes will always come in as a tuple no matter what 

>>> recurse(example) 
>>> recurse(example, example, example) 

और अगर आप मूल रूप से बॉक्स मदों की एक सूची के साथ शुरू, आप इसे करने से पारित कर सकते हैं:

>>> boxes = [example, example, example] 
>>> recurse(*example) # this will unpack your list into args 
+0

को ट्रैक करें, मुझे स्थानीय रूप से एक सूची में बॉक्स को कनवर्ट करने के साथ अपनी पहली चाल पसंद है। इसके अलावा लपेटा हुआ कार्य दो अलग-अलग कार्यों के मुकाबले बहुत बेहतर पढ़ता है। तदनुसार मेरे कोड को संपादित करेगा और –

+0

की रिपोर्ट करें अच्छी तरह से समझाया और पूरी तरह से काम किया। आपके कोड ने मुझे अच्छी तरह से शिक्षित किया, मैं बजाय कोडिंग उत्तर देने के बजाय शिक्षित होना चाहूंगा। धन्यवाद –

+0

@ हैकिंग लाइफ: आम तौर पर मैं सिर्फ आपके कोड उदाहरण पर टिप्पणी करूंगा। शुरुआत में सभी लोग देखना चाहते हैं कि आपने क्या प्रयास किया है और आप कहां फंस गए हैं। आपने जो लिखा है उसे देखने के बाद, मैंने अभी फैसला किया है कि आपके पास पहले से ही सही अवधारणा है। खुशी है कि यह आपके लिए काम करता है! – jdi

1

साथ काम कर रहा है आप दो है विकल्प:

  1. अतिरिक्त जानकारी को अपने रिकर्सन में अतिरिक्त पैरामीटर के रूप में ट्रैक रखें, उदाहरण के लिए myRecursiveFunction(..., ancestry=[])
  2. प्रत्येक बॉक्सइटम अपने माता-पिता का ट्रैक रखें, जब भी यह बॉक्सइटम में एम्बेडेड होता है (__init__ कन्स्ट्रक्टर में, प्रत्येक बच्चे के लिए child.parent = self सेट करें)। यदि आप एक से अधिक बॉक्स में BoxItem रखने की योजना बना रहे हैं तो यह बुरा है।
+0

क्यों क्या यह ओपीएस वास्तविक प्रश्न के आधार पर आवश्यक है? वह सिर्फ एक बॉक्सिंगम की 'बॉक्स इटम्स' विशेषता सूची को लूप करने के लिए एक रिकर्सिव फ़ंक्शन चाहता है। ऐसा करने के लिए अपने वर्तमान वर्ग में कुछ भी नहीं है। बस एक पुनरावर्ती समारोह। – jdi

+0

@jdi: यह सही है, विकल्प # 1 देखें। हालांकि, उस पुनरावर्ती कार्य में, कॉल की याददाश्त होनी चाहिए; फिर विकल्प # 1 देखें (विकल्प विकल्प # 2 है)। – ninjagecko

+0

आह, मैंने इसे और अधिक सावधानी से पढ़ा। मैं अपनी टिप्पणी वापस लेता हूं :-) आपका पहला सुझाव सही है। आपको कुछ गहराई से ट्रैक करना है कि आपकी गहराई – jdi

संबंधित मुद्दे