You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求将NPV计算的for循环转为递归函数,求递归原理讲解

把NPV循环代码转成递归函数 + 递归入门讲解

递归版NPV代码

rate, cashflows = 0.05, [-1100, 300, 450, 800]

def npv_recursive(rate, cashflows):
    def helper(i, current_npv):
        # 基线条件:所有现金流处理完毕,停止递归
        if i == len(cashflows):
            return
        # 计算当前现金流的现值,累加到已有NPV上
        new_npv = current_npv + cashflows[i] / (1 + rate)**i
        print(round(new_npv, 3))
        # 递归调用:处理下一个现金流,更新索引和累计NPV
        helper(i + 1, new_npv)
    
    # 初始调用:从第0个现金流开始,初始累计NPV为0
    helper(0, 0)

# 测试调用
npv_recursive(rate, cashflows)

递归核心知识讲解

递归就是函数自己调用自己,把一个大问题拆成一个个和原问题逻辑一致的小问题,直到遇到“不能再拆”的基线条件,就停止调用并返回结果。

递归的两个必备要素

  • 基线条件:必须有明确的终止点,否则函数会无限调用自己,直接撑爆内存栈。比如上面代码里的if i == len(cashflows): return,当所有现金流都处理完,就停止递归。
  • 递归步骤:把当前问题拆解成更小的子问题,调用自身解决子问题,再把子问题的结果组合起来。比如这里,处理第i个现金流的问题,拆解成“先算第i个的现值加到累计值里,再处理第i+1个现金流”。

对应原循环的逻辑对比

原循环是从i=0到i=3,手动跟踪累计NPV和当前索引;递归版本用helper函数自动维护两个状态:

  • i:当前处理到第几个现金流
  • current_npv:到当前为止累计的NPV值

每次递归调用都会完成三件事:

  1. 检查是否处理完所有现金流(触发基线条件则停止)
  2. 计算当前现金流的现值,更新累计NPV并打印
  3. 调用自己处理下一个现金流

递归与循环的优劣

  • 递归代码更贴合问题的自然逻辑,写法简洁,但如果递归深度过大(比如现金流有几万个),会占用更多栈内存,甚至触发栈溢出错误。
  • 循环的内存占用更稳定,但需要手动跟踪状态(比如原循环里的NPV变量和i索引)。

内容的提问来源于stack exchange,提问作者user9110693

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:15:34