Lisp:添加列表列表的各个元素

Kot*_*pou 1 lisp nested common-lisp

假设我有一个清单:

((1 2 3) (8 4 7) (41 79 30) (0 8 5))
Run Code Online (Sandbox Code Playgroud)

我想做这个:

(1+8+41+0 2+4+79+8 3+7+30+5) = (50 93 45)
Run Code Online (Sandbox Code Playgroud)

我找到了一个丑陋的解决方案:

(defun nested+ (lst)
  (let ((acc nil))
    (dotimes (i (length (first lst)))
      (push (apply #'+ (mapcar #'(lambda (a) (nth i a)) lst)) acc))
    (reverse acc)))
Run Code Online (Sandbox Code Playgroud)

它似乎适用于我的目的,但我想这是缓慢而且没有lispy.什么是正确的方法?

Xac*_*ach 7

一种选择是(apply #'mapcar #'+ list).Mapcar会消耗尽可能多的列表,并在到达最短列表末尾时停止.

  • @ Gwang-JinKim:在ABCL中 - JVM上的Common Lisp - 它只有50个.没有那么多. (2认同)
  • @Gwang-JinKim:即使在 CLISP 中,4096 个元素的列表也不是很长! (2认同)

Gwa*_*Kim 5

天真的解决方案是

(apply #'mapcar #'+ list)
Run Code Online (Sandbox Code Playgroud)

然而,正如已经指出如这里由计算器这里由LispWorkscall-arguments-limit(在最坏的情况下)50点的参数适用于由调用的函数apply.并reduce建议来代替.

因此,我建议:

(defun sum-all (lists)
  (reduce #'(lambda (l1 l2) (mapcar #'+ l1 l2)) lists))
Run Code Online (Sandbox Code Playgroud)

确实如此

(sum-all '((1 2 3) (8 4 7) (41 79 30) (0 8 5)))
;; (50 93 45)
Run Code Online (Sandbox Code Playgroud)