Python Reduce函数 - 用Scheme编写

时间:2011-02-24 04:18:26

标签: scheme reduce

晚间!

我需要在Scheme中编写 reduce 函数,该函数与Python中的内置 reduce 函数一样。在Scheme中编写reduce函数很容易:

(define (reduce fn lis identity)
  (if (null? lis)
    identity
    (fn (car lis)
        (reduce fn (cdr lis) identity))))

但是,此代码与Python reduce 不同,后者仅使用两个参数(函数和要减少的项列表)。

任何人都可以帮助我编写一个以这种方式工作的Scheme函数吗?

(>(reduce *'(2 4 5 5))=> 200,是我们教授的例子。)

非常感谢,伙计和女孩们。你很有帮助< 3

ETA:对Levien先生和Jester-Young先生,非常感谢你。您提供了大量的信息,以帮助我自己解决问题。 *拥抱

3 个答案:

答案 0 :(得分:5)

这很容易。使用列表的第一个元素初始化累加器:

(define (py-reduce f ls) (fold f (car ls) (cdr ls)))

(py-reduce * '(2 4 5 5)) => 200

随意使用另一种减少功能而不是从srfi-1折叠(如减少,折叠......)或使用自己的减少功能。你的清单至少需要一个元素。

答案 1 :(得分:2)

拥有一个标识允许你的函数使用大小为零或更多的列表 - 当它是一个空列表时,你就获得了标识。如果没有标识,该函数将仅使用一个或多个元素的列表。一些函数自然具有一个同一性(零用于加法,一个用于乘法等)。其他人则不会 - 尤其是minmax,特别是大in。

你应该能够弄清楚其余部分:)

答案 2 :(得分:0)

下面是一个尾递归版本。你的教授不太喜欢它(因为它没有演示递归;-)),但至少它会让你知道如何去做。

(define (reduce func lst)
  (let loop ((val (car lst))
             (lst (cdr lst)))
    (if (null? lst) val
        (loop (func val (car lst)) (cdr lst)))))

正如Raph Levien的优秀答案所示,如果传入列表为空(这就是identity参数的用途),此版本将无效。在这种情况下,您将收到错误(因为您不能carcdr为空列表。