使用dolist宏汇总列表

时间:2019-01-11 10:32:59

标签: common-lisp

我试图通过使用dolist宏来汇总列表。但是,我做不到。它总是返回列表的最后一个元素。预先感谢。

(defun sumlist2 (l)
  ;;this function computes total of a list by using dolist macro
  (let ((summ 0))
    (dolist (obj l)
      (setf summ (+ obj)))
    summ))

4 个答案:

答案 0 :(得分:7)

dolist的正文中,您没有将变量summ的值求和,而是为其分配了列表元素的值,因为(+ obj)的总和是{{ 1}},没有其他值,因此本身返回obj。换句话说,代替:

obj

您应该写:

(setf summ (+ obj))

或者甚至更好:

(setf summ (+ summ obj))

执行加法。

最后请注意,您可以直接从(incf summ obj) 生成结果,例如:

dolist

答案 1 :(得分:5)

Lisp中的+函数是不可变的,它只是计算一个新值:

(+)         is zero
(+ x)       is just x
(+ x y ...) is the sum of x, y, etc.

在您的代码中,您setf是本地summ变量,每个值都来自列表。 最终,它仅包含列表的最后一个值。如果要更新summ,则需要执行以下操作:

(setf summ (+ summ obj))

或者,简单地:

(incf summ obj)

答案 2 :(得分:1)

loop供您参考:

(loop for i in '(1 2 3) sum i)
;; 6

(reduce #'+ '(1 2 3))

查看更多:https://lispcookbook.github.io/cl-cookbook/iteration.html#summation

答案 3 :(得分:0)

下面我有一个可以为您工作的函数的示例,然后将解释您的错误:

(defun sum-list(lst)
  (let((sum 0))
    (dolist(l lst)
      (setf sum (+ sum l)))
     sum))

代替:

(setf sum (+ obj))

我们将上次迭代中已经获得的列表的总和添加到当前正在迭代的列表中的数字上:

(sum-list ‘(1 2 3 4 5 6 7))
28

下面,我们可以传递一个整数列表1-7,该列表将返回值28。