将列表项添加在一起

Adding List Items together

我有一个列表,我想要 add/concatenate 元素。

((a b) (c d) (e f)) -> ((a b c d) (a b e f) (c d e f))

这是它应该的样子。 List 从来没有固定大小,因此它也可以只是两个或三个以上的元素。我试过使用循环,但是 returns 很多我不想要的额外列表。

(setq a '((a b) (c d) (e f))
(setq b '((a b) (c d) (e f))
(loop for x in a
              append (loop for y in b
                           collect (append x y)))

结果:

((A B A B) (A B C D) (A B E F) (C D A B) (C D C D) (C D E F) (E F A B) (E F C D) (E F E F))

有没有办法限制循环?还是有比使用循环更好的方法?我不知道如何调用它,所以我无法找到我的问题的任何答案。

您希望从该点开始将列表的每个元素与列表尾部的每个元素连接起来。要获取列表的所有尾部,我们使用 loop 关键字 on 而不是 in.

(loop for (x . tail) on a
      append (loop for y in tail
                   collect (append x y)))

在第一个循环中使用 on 而不是 in 使循环变量等于 cons 单元格,而不仅仅是它们的 car。因此,您原来的外循环会产生值

(a b)
(c d)
(e f)

我的外循环将产生

((a b) (c d) (e f))
((c d) (e f))
((e f))

然后我们立即解构它,所以 x 将成为列表的元素,而 tail 在每次迭代中将成为该点之后列表的其余部分,即确切的东西我们想在我们的内部循环中迭代。其他一切都与您已经想到的完全一样。


所有晦涩难懂的 loop 构造可能有点难以理解。我发现最好的参考是 this chapter from the Practical Common Lisp book (the entire book 可以免费在线获得,我强烈推荐给学习 Lisp 的人)