(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1))
(if (!= x e)
((my_append e list2 )
(setf y cdr(list1))
(my_remove(e y list2)))
((setf y cdr(list1))
(my_remove(e y list2))
)))))
我正在尝试编写一个函数来从列表中删除一个元素,但是我收到一个错误“它应该是lambada函数”而且我不知道我的代码是正确还是错误。
答案 0 :(得分:1)
您的代码存在一些问题。首先,让我们用标准缩进来看待它
(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1)) ; (i)
(if (!= x e)
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
((setf y cdr(list1)) ; (v)
(my_remove(e y list2))))))) ; (vi)
每个标记的行都有问题。 Lisp中函数调用的语法是
(function argument…)
这意味着在您的行(i)
中,您尝试使用参数(setf x car(list1))
调用名为(if (!= x e) …)
的函数。当然,这不是一个函数的名称,我怀疑即使它是,你也不想用参数(if (!= x e) …)
来调用它。同样
(setf x car (list1))
尝试将x
设置为变量car
的值(并且没有一个),然后为地点(list1)
分配新值。由于函数调用的语法是(function argument…)
,因此您需要:
(setf x (car list1))
如果您尝试对表单进行排序,可以考虑使用cond
,其中您可以提供多个表单,或progn
(请参阅In Common Lisp, why do multi-expression bodies of (if) statements require (progn)?)。
例如,而不是
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
你可能想要
(progn
(my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
但是,你也会遇到一些问题。在(iii)
和(iv)
中,您需要使用(cdr list1)
和(my_remove e y list2)
,如上所述,但您也遇到了正在评估的问题{{1}和(ii)
,但你丢弃了价值。
如果您考虑(iii)
的简单定义,我认为可能对您有利。通常,列表是空列表my-remove
或cons列表,其列车是列表的第一个元素,其cdr是列表的其余部分。您可以使用这样的定义,然后:
在代码中,它看起来像:
()
(defun my-remove (element list)
(if (endp list)
list
(if (eql element (first list))
(my-remove element (rest list))
(list* (first list)
(my-remove element (rest list))))))
那些嵌套的CL-USER> (my-remove 1 '(1 2 3 1 2 3))
(2 3 2 3)
看起来有点难看,你可能想在这里使用if
,即使你不需要它允许的多个表达式主体:
cond
由于没有正文,其测试形式的计算结果为true的(defun my-remove (element list)
(cond
((endp list)
list)
((eql element (first list))
(my-remove element (rest list)))
(t
(list* (first list) (my-remove element (rest list))))))
子句返回测试表单的值,您甚至可以使最后一个子句更简单:
cond