我刚刚开始使用Lisp (Common-Lisp),这里有一个计算数字列表平均值的函数
CL-USER> (defun average (list) (/ (apply #'+ list) (length list)))
AVERAGE
CL-USER> (average '(1 2 3 4))
5/2但是,如果我像这样重写函数
CL-USER> (defun average (list) (/ (+ list) (length list)))它不能工作,因为(+‘(数字列表))不能被计算,因此长度的争论和+中的表达式是不兼容的。
有没有一种诱骗(列表)的方法,可以通过+自然地将其计算为表达式,并作为数据传递给长度?而不是使用apply #‘
我试过了:
(defun average (list) (/ (+ list) (length '(list))))但这似乎也不能解决这个问题!
发布于 2014-10-02 08:17:46
请参阅Common lisp: How many argument can a function take?
最好使用(reduce #'+ list)而不是(apply #'+ list),因为apply受到函数可以接受的参数数量的限制。
因此,您的平均函数应该如下所示:
(defun average (list)
(/ (reduce #'+ list)
(length list)))顺便说一句,代码(length '(list))返回1,因为它返回包含符号列表“”的列表的长度。
发布于 2014-10-02 14:09:16
没有理由不使用APPLY或更好的REDUCE。这里的REDUCE是正确的函数。
如果你用Lisp编程,大多数时候你必须使用一个符号,命名你的操作,后跟参数。这是Lisp中通用的基本表达式样式。你可能希望有更短的方法来写一些东西,比如用一个函数减少一个列表。但在basic Lisp中没有。
(+ (list 1 2 3 4))是一个错误,因为+需要的是数字,而不是列表。
如果你想对一个列表中的所有数字求和,你必须使用REDUCE。此操作也称为折叠。
对列表中的数字求和:
(reduce #'+ (list 1 2 3 4))另一种简单的方法是使用LOOP
(loop for n in (list 1 2 3 4) sum n)编写像(length '(list))这样的代码没有任何意义,因为您引用的是一个列表。带引号的列表被视为数据而不是代码。因为它是常量数据,所以结果总是1。
获得短程序的Lisp方法之一是建立可重用函数的词汇表。其中一个不使用最短的符号,而是使用明显的名称创建可重用的函数。因此,如果我们求和很多,我们编写一个sum函数:
(defun sum (list)
(reduce #'+ list))那么average就是:
(defun average (list)
(/ (sum list) (length list)))https://stackoverflow.com/questions/26152557
复制相似问题