2012-04-22 19 views
8

में रिकर्सिव जेनरेटर मैंने उप-स्ट्रिंग्स के प्रत्येक अद्वितीय संयोजन वाले एक जेनरेटर को वापस करने के लिए एक फ़ंक्शन लिखा जिसमें प्राथमिक स्ट्रिंग से एन तत्वों से अधिक तत्व शामिल हैं।पाइथन

एक उदाहरण के रूप में:

अगर मैं 'abcdefghi' और दो की लंबाई की जांच, और सूची के अनुसार 4 तत्वों की एक सीमा मैं पाने के लिए करना चाहते हैं:

['ab', 'cd', 'ef', 'gh'] 
['ab', 'de', 'fg', 'hi'] 
['bc', 'de', 'fg', 'hi'] 

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

def get_next_probe(self, current_probe_list, probes, unit_length): 
    if isinstance(current_probe_list, list): 
     last_probe=current_probe_list[-1] 
     available_probes = [candidate for candidate in probes if candidate.start>last_probe.end] 
    else: 
     available_probes = [candidate for candidate in probes if candidate.start<unit_length] 

    if available_probes: 

     max_position=min([probe.end for probe in available_probes]) 
     available_probes2=[probe for probe in available_probes if max_position+1>probe.start] 

     for new_last_probe in available_probes2: 
      new_list=list(current_probe_list) 
      new_list.append(new_last_probe) 
      self.get_next_probe(new_list, probes, unit_length) 

    else: 
     if len(current_probe_list)>=self.num_units: 
      yield current_probe_list 

यदि उपज प्रिंट करने के लिए उपज बदल जाती है तो यह ठीक है! मैं जो भी मदद प्राप्त कर सकता हूं उसकी सराहना करता हूं। मुझे एहसास है कि यह इस प्रकार की खोज समस्या का इष्टतम कार्यान्वयन नहीं है, ऐसा लगता है कि get_next_probe की अंतिम कॉल से मिली पोजीशन की सूची लौटने की तरह और इस सूची को उन तत्वों के लिए फ़िल्टर करना जो new_last_probe.end को ओवरलैप नहीं करते हैं, वे अधिक कुशल होंगे ... लेकिन यह मेरे लिए लिखना बहुत आसान था। किसी भी एल्गोरिदम इनपुट की सराहना की जाएगी।

धन्यवाद!

+2

आपके पास प्रतीत होता है कि आपके रिकर्सिव कॉल से परिणाम का उपयोग नहीं किया जा रहा है। मैं एक आंतरिक लूप को देखने की उम्मीद करता हूं जो बाहरी सूची के एक उपन्यास पर पुनरावृत्त होता है, जो परिणामस्वरूप उत्पन्न होने वाले परिणाम को बनाने के लिए एक पुनरावर्ती कॉल से परिणाम को जोड़ता है। –

+0

आप पहली पंक्ति, एबी, –

उत्तर

17

मैंने सोचा था कि एक जनरेटर आवश्यक के रूप में प्रत्यावर्तन छेद नीचे जहाँ तक पूर्व में होना होगा, जब तक यह उपज बयान

यह ठीक recurse होगा, लेकिन बाहर की ओर वापस प्रचार करने के लिए yield एड मूल्य प्राप्त करने के मारा, आपको इसे स्पष्ट रूप से करने की आवश्यकता है - जैसे कि यह return था, आपको प्रत्येक रिकर्सन का परिणाम स्पष्ट रूप से return करना होगा। तो, के बजाय:

self.get_next_probe(new_list, probes, unit_length) 

आप की तरह कुछ करना होगा:

for val in self.get_next_probe(new_list, probes, unit_length): 
    yield val 

या यदि आप अजगर 3.3 या नए प्रयोग कर रहे हैं, तो आप भी ऐसा कर सकते हैं:

yield from self.get_next_probe(new_list, probes, unit_length) 
+3

पर एक उद्धरण खो रहे हैं पाइथन 3.2 में, आप केवल self.get_next_prob (...) से उपज भी कर सकते हैं। – Dougal

+1

@ डौगल, 'से उपज '3.2 में नहीं है, लेकिन यह बाहर आने के बाद 3.3 में होगी। – lvc

+0

अच्छा बिंदु @ आईवीसी ... आप यह कहने से पहले मैं इसे देख सकता था, क्योंकि मैं इन दिनों 3.2 में अपना अधिकांश कोड लिखता हूं। :) – Dougal