【问题标题】:Balancing memory and performance in using yield in recursion在递归中使用 yield 平衡内存和性能
【发布时间】:2013-05-24 05:47:57
【问题描述】:

我有一个产生排列的函数:

def all_perms(str):
    if len(str) <=1:
        yield str
    else:
        for perm in all_perms(str[1:]):
            for i in range(len(perm)+1):
                yield perm[:i] + str[0:1] + perm[i:]

据我了解,yield 即时计算结果,而不是将中间计算存储在堆上。这很好,因为 python 是not aggressive at freeing up memory。但是it takes longer to calculate。这是否意味着,它实际上每次调用时都必须计算递归树的整个一个分支?如果是这种情况,运行时间的时间复杂度将增加 N*log(N),对吗?

如果确实yield每次都需要计算整个一个分支, 在每一层,计算都需要与孩子的数量成比例地重复,每一层加起来为 N。由于深度是 log(N),所以总数是 N*log(N)。这似乎是一笔太大的交易。何时使用 yield 或更好的替代方案是否有良好的经验法则?

【问题讨论】:

    标签: python algorithm recursion time-complexity yield


    【解决方案1】:

    如果您检查documentation,您将看到yield 冻结了生成器的状态。当控制流返回时,就像是外部调用一样,所以所有状态都被保留了。

    因此,由于运行时复杂度没有差异,我不会过多担心列表和生成器之间的性能差异。如果您处理大型集合,生成器的内存节省方面值得考虑,以及创建“无限”集合的能力。

    另外,itertools.permutations

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多