2016-07-11 23 views
-3

我无法弄清楚为什么下面的函数不工作。我试图让它返回列表显示了所有组合的列表:((1 5) (1 6) (1 7) (2 5) (2 6) (2 7) (3 5) (3 6) (3 7))为什么收集函数在这个Lisp代码中不起作用

(defun combo3 (list1 list2) 
    (dolist (e1 list1) 
     (dolist (e2 list2) 
      collect '(e1 e2)))) 


> (combo3 '(1 2 3) '(5 6 7)) 
NIL 

编辑:在回答的答案,我试图用循环宏与收集。收集不在以下循环中工作:

(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 

我试图使其工作没有nconc。收集总是需要nconc?

+0

'COLLECT'不是一个函数。它是'LOOP'宏的一部分,因此只能在'LOOP'中使用。 – jkiiski

+0

重新编辑:内部循环中的COLLECT会创建子列表,因此您需要外部循环来将子句加入到单个列表中。另外,你不应该在那里有那些'DO'。 'DO'不是'FOR ... IN ...'构造的一部分,而是一个用于执行表单的独立语句(比如'COLLECT'和'NCONC',除了'DO'丢弃结果外)。 – jkiiski

+0

[Lisp:如何从列表中包含的列表中获取所有可能的元素组合?](http://stackoverflow.com/questions/18675913/lisp-how-to-get-all-possible-combinations包含元素的列表) – anquegi

回答

3

几个问题...

首先,collectloop宏的一部分(或设施,如果你喜欢),所以会内dolist使用时会出现问题。

其次,即使collect '(e1 e2)收集的东西,它(可能)不会是你想要的,因为它会与像((e1 e2) (e1 e2) (e1 e2) (e1 e2) (e1 e2) (e1 e2))列表结束。

你(可能)要的是一样的东西:

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

没有nconc,它不起作用。请参阅我的问题中的编辑。 – rnso

+0

@rnso内部循环使用'collect'来建立三个列表,'((1 4)(1 5)(1 6))'和2和3类似。这些返回到我们想要的外部循环结合起来。这可以使用'nconc'或'append'完成,但在这种情况下我们知道*我们有新的列表,所以我们不妨使用'nconc'来破坏性地连接它们。你需要在外循环中进行某种累加,否则它只返回'nil'。作为一般规则,请不要编辑您的问题以提出新问题,只需提出一个新问题即可。 – Vatine

相关问题