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

如何在Scheme标准差计算代码中运用map、apply、filter函数?

用map、apply优化标准差计算函数

你已经在average函数里很好地运用了apply来对列表元素求和,接下来我们可以把map和apply结合起来,简化剩余代码,让它更贴合函数式编程的风格,同时也能理解这几个工具的用法。

改造summation函数

原summation通过递归计算每个元素与均值差的平方和,我们可以用map批量处理列表中的每个元素,生成所有平方值的列表,再用apply +完成求和:

(define (average li)
  (/ (apply + li) (length li)))

(define (summation li avg)
  (apply + (map (lambda (x) (* (- x avg) (- x avg))) li)))

这里的map接收一个匿名函数(lambda (x) (* (- x avg) (- x avg))),把这个函数映射到列表li的每一个元素上,得到一个新列表——里面全是每个元素与均值差的平方值。然后用apply +把新列表的所有元素加起来,完全替代了原来的递归逻辑,代码更简洁直观。

简化标准差函数sd

我们可以把逻辑整合到sd里,让结构更紧凑:

(define (sd li)
  (let ((avg (average li)))
    (sqrt (/ (summation li avg) (length li)))))

如果想进一步精简,甚至可以把summation的逻辑直接内联到sd中,减少函数定义的数量:

(define (sd li)
  (let ((avg (average li)))
    (sqrt (/ (apply + (map (lambda (x) (expt (- x avg) 2)) li))
             (length li)))))

这里用expt计算平方,和(* (- x avg) (- x avg))效果一致,只是写法更简洁。

关于filter的运用

如果你的场景需要过滤掉特定元素(比如异常值、空值),filter就能发挥作用。比如计算标准差时排除列表中的负数:

(define (sd-with-filter li)
  (let ((filtered-li (filter (lambda (x) (>= x 0)) li)) ; 筛选出非负数元素
        (avg (average li)))
    (sqrt (/ (apply + (map (lambda (x) (expt (- x avg) 2)) filtered-li))
             (length filtered-li)))))

filter接收一个判断条件的函数,返回符合条件的元素组成的新列表,让我们能在计算前先对数据做清洗。

核心工具总结

  • map:对列表的每个元素执行相同操作,批量生成新列表
  • apply:把一个函数应用到列表的所有元素上(比如apply + li就是把+作用在li的所有元素上求和)
  • filter:根据条件筛选列表元素,得到符合要求的子列表

这样改造后的代码更符合函数式编程的风格,避免了手动递归的繁琐,也更易读维护。

内容的提问来源于stack exchange,提问作者Renato D' Oyague

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:27:49