首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用#‘或不应用#’

应用#‘或不应用#’
EN

Stack Overflow用户
提问于 2014-10-02 07:58:51
回答 2查看 140关注 0票数 0

我刚刚开始使用Lisp (Common-Lisp),这里有一个计算数字列表平均值的函数

代码语言:javascript
复制
CL-USER> (defun average (list) (/ (apply #'+ list) (length list)))
AVERAGE
CL-USER> (average '(1 2 3 4))
5/2

但是,如果我像这样重写函数

代码语言:javascript
复制
CL-USER> (defun average (list) (/ (+ list) (length list)))

它不能工作,因为(+‘(数字列表))不能被计算,因此长度的争论和+中的表达式是不兼容的。

有没有一种诱骗(列表)的方法,可以通过+自然地将其计算为表达式,并作为数据传递给长度?而不是使用apply #‘

我试过了:

代码语言:javascript
复制
(defun average (list) (/ (+ list) (length '(list))))

但这似乎也不能解决这个问题!

EN

回答 2

Stack Overflow用户

发布于 2014-10-02 08:17:46

请参阅Common lisp: How many argument can a function take?

最好使用(reduce #'+ list)而不是(apply #'+ list),因为apply受到函数可以接受的参数数量的限制。

因此,您的平均函数应该如下所示:

代码语言:javascript
复制
(defun average (list)
  (/ (reduce #'+ list)
     (length list)))

顺便说一句,代码(length '(list))返回1,因为它返回包含符号列表“”的列表的长度。

票数 5
EN

Stack Overflow用户

发布于 2014-10-02 14:09:16

没有理由不使用APPLY或更好的REDUCE。这里的REDUCE是正确的函数。

如果你用Lisp编程,大多数时候你必须使用一个符号,命名你的操作,后跟参数。这是Lisp中通用的基本表达式样式。你可能希望有更短的方法来写一些东西,比如用一个函数减少一个列表。但在basic Lisp中没有。

(+ (list 1 2 3 4))是一个错误,因为+需要的是数字,而不是列表。

如果你想对一个列表中的所有数字求和,你必须使用REDUCE。此操作也称为折叠。

对列表中的数字求和:

代码语言:javascript
复制
(reduce #'+ (list 1 2 3 4))

另一种简单的方法是使用LOOP

代码语言:javascript
复制
(loop for n in (list 1 2 3 4) sum n)

编写像(length '(list))这样的代码没有任何意义,因为您引用的是一个列表。带引号的列表被视为数据而不是代码。因为它是常量数据,所以结果总是1

获得短程序的Lisp方法之一是建立可重用函数的词汇表。其中一个不使用最短的符号,而是使用明显的名称创建可重用的函数。因此,如果我们求和很多,我们编写一个sum函数:

代码语言:javascript
复制
(defun sum (list)
  (reduce #'+ list))

那么average就是:

代码语言:javascript
复制
(defun average (list)
  (/ (sum list) (length list)))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26152557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档