为什么collect函数在此Lisp代码中不起作用

为什么collect函数在此Lisp代码中不起作用,lisp,common-lisp,Lisp,Common Lisp,我无法理解为什么下面的函数不起作用。我试图让它返回一个显示所有组合的列表:1 5 1 6 1 7 2 5 2 6 2 7 3 5 3 6 3 7 编辑:作为对答案的回应,我尝试将循环宏与collect一起使用。Collect在以下循环中不工作: (defun combo4 (list1 list2) (loop for element1 in list1 do (loop for element2 in list2 do collect (l

我无法理解为什么下面的函数不起作用。我试图让它返回一个显示所有组合的列表:1 5 1 6 1 7 2 5 2 6 2 7 3 5 3 6 3 7

编辑:作为对答案的回应,我尝试将循环宏与collect一起使用。Collect在以下循环中不工作:

(defun combo4 (list1 list2)
   (loop for element1 in list1 do 
        (loop for element2 in list2 do
               collect (list element1 element2))))

> (combo4 '(1 2 3) '( 5 6 7) )
NIL
我试着让它在没有NCOC的情况下工作。collect是否总是需要NCOC?

有几个问题

首先,如果您愿意,collect是循环宏或工具的一部分,所以在dolist中使用时会导致问题

第二,即使collect'e1e2确实收集了一些东西,它也可能不是您想要的,因为它最终会得到一个类似于e1e2e1e2e1e2e1e2e1e2e1e2e2的列表

您可能想要的是:

(defun cross-product (list1 list2)
   (loop for element1 in list1
      nconc (loop for element2 in list2
               collect (list element1 element2))))

COLLECT不是一个函数。它是循环宏的一部分,因此只能在循环内使用。重新编辑:内部循环中的COLLECT创建子列表,因此需要外部循环有一个子句将这些子列表连接到单个列表中。还有,你不应该在那里有那些DOs。“做”不是“做”的一部分。。。在里面相反,它是一个单独的语句,用于执行COLLECT和ncoc之类的表单,但DO会丢弃结果。如果没有ncoc,它的可能副本将无法工作。请参阅我的问题中的编辑。@rnso内部循环使用collect构建三个列表,1 4 1 5 1 6,2和3也是如此。这些被返回到外部循环,在那里我们想要合并它们。这可以使用ncoc或append来完成,但在本例中,我们知道我们有新列表,所以我们也可以使用ncoc以破坏性方式连接它们。您需要在外循环中进行某种累加,否则它只返回nil。一般来说,请不要为了问一个新问题而修改你的问题,而只是问一个新问题。
(defun cross-product (list1 list2)
   (loop for element1 in list1
      nconc (loop for element2 in list2
               collect (list element1 element2))))