2012-04-22 101 views
8

我寫了一個函數來返回一個包含給定長度的子字符串的每個唯一組合的生成器,該字符串包含來自主字符串的超過n個元素。Python中的遞歸生成器

作爲例證:

如果我有「ABCDEFGHI」和兩種長度的探針,並且每個列表4個元件的閾值I想獲得:

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

我的第一試圖解決這個問題涉及到返回列表的列表。這最終溢出了計算機的內存。作爲一個粗略的二級解決方案,我創建了一個類似的發電機。問題是我創建了一個自己調用的嵌套生成器。當我運行這個函數時,它似乎只循環內部的for循環,而沒有實際再次調用它自己。我認爲發電機會根據需要在遞歸井之前儘可能遠地前進,直到達到產量聲明。任何線索發生了什麼?

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

你不似乎不會使用遞歸調用的結果。我期望看到一個循環遍歷外部列表的子節點的內部循環,連接遞歸調用的結果以形成結果。 – 2012-04-22 01:38:07

+0

您在第一行ab也缺少一個報價 – 2012-04-22 02:17:19

回答

17

我認爲,一個發電機會盡量先向下遞歸孔必要的,直到它擊中了yield語句

它會重複罰款,但要獲得yield ED值傳播完成背朝外,你需要明確地做 - 就像它是一個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 

或者,如果你正在使用Python 3.3或更新版本,你也可以這樣做:

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

從Python 3.2開始,您也可以只從'self.get_next_prob(...)'產生yield。 – Dougal 2012-04-22 02:31:08

+1

@Dougal,從'產出'不在3.2,但一旦出現就會在3.3。 – lvc 2012-04-22 03:05:04

+0

好點@Ivc ...在這麼說之前,我可以檢查一下,因爲無論如何,我現在寫的大部分代碼都是3.2。 :) – Dougal 2012-04-22 03:48:41