【问题标题】:Recursive Generators in PythonPython 中的递归生成器
【发布时间】:2012-05-03 02:45:49
【问题描述】:

我编写了一个函数来返回一个生成器,该生成器包含给定长度的子字符串的每个唯一组合,其中包含来自主字符串的 n 个以上元素。

作为说明:

如果我有 'abcdefghi' 和长度为 2 的探针,并且每个列表的阈值为 4 个元素,我想获得:

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

我对这个问题的第一次尝试涉及返回一个列表列表。这最终溢出了计算机的内存。作为粗略的辅助解决方案,我创建了一个执行类似操作的生成器。问题是我创建了一个调用自身的嵌套生成器。当我运行这个函数时,它似乎只是在内部 for 循环中循环,而实际上并没有再次调用它自己。我认为生成器会根据需要在递归漏洞之前尽可能远,直到它遇到 yield 语句。有什么线索吗?

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 的元素会更有效率...但这对我来说写起来容易得多。任何算法输入仍将不胜感激。

谢谢!

【问题讨论】:

  • 您似乎没有使用递归调用的结果。我希望看到一个内部循环遍历外部列表的子光照,将递归调用的结果连接起来形成产生的结果。
  • 你也错过了第一行的报价,ab,

标签: python recursion generator bioinformatics


【解决方案1】:

我认为生成器会在必要的情况下先于递归漏洞,直到它遇到 yield 语句

它会很好地递归,但要让 yielded 值向外传播,您需要明确地执行它 - 就像它是 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)

【讨论】:

  • 从 Python 3.2 开始,你也可以只做yield from self.get_next_prob(...)
  • @Dougal , yield from 不在 3.2 中,但一旦出现就会在 3.3 中。
  • 好点@Ivc ...你会在这么说之前检查一下,因为这些天我的大部分代码都是在3.2中编写的。 :)
猜你喜欢
  • 2021-05-22
  • 2016-05-03
  • 2017-06-26
  • 2016-04-03
  • 1970-01-01
  • 2013-09-16
  • 2013-05-19
  • 2010-10-25
  • 2021-10-17
相关资源
最近更新 更多