【问题标题】:Why collect function does not work in this Lisp code为什么收集功能在此 Lisp 代码中不起作用
【发布时间】:2016-07-11 16:28:07
【问题描述】:

我无法弄清楚为什么以下功能不起作用。我试图让它返回一个显示所有组合的列表列表:((1 5) (1 6) (1 7) (2 5) (2 6) (2 7) (3 5) (3 6) (3 7))

(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 的情况下工作。 collect 总是需要 nconc 吗?

【问题讨论】:

  • COLLECT 不是函数。它是LOOP-macro 的一部分,因此只能在LOOP 中使用。
  • 重新编辑:内部循环中的COLLECT 创建子列表,因此您需要外部循环有一个子句将它们连接到一个列表中。此外,您不应该在那里拥有那些DOs。 DO 不是 FOR ... IN ... 构造的一部分,而是用于执行表单的单独语句(如 COLLECTNCONC,除了 DO 丢弃结果)。

标签: lisp common-lisp


【解决方案1】:

几个问题...

首先,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))))

【讨论】:

  • 没有 nconc 是不行的。请参阅我的问题中的编辑。
  • @rnso 内部循环使用collect 构建三个列表,((1 4) (1 5) (1 6)) 和类似的 2 和 3。这些返回到外部循环,我们想要将它们组合起来。这可以使用nconcappend 来完成,但在这种情况下,我们知道我们有新的列表,所以我们不妨使用nconc 破坏性地连接它们。您需要在外循环中进行某种累积,否则它只会返回nil。作为一般规则,请不要编辑您的问题以提出新问题,只需提出新问题即可。
猜你喜欢
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 2011-10-25
相关资源
最近更新 更多