从LISP中的子列表中删除列表中的所有nils

时间:2016-04-06 21:21:22

标签: list null lisp

我有一个包含多个子列表的列表。其中一些有我需要摆脱的NIL元素。我只能使用基本功能(NOT,EQL,CONS等..)

(defun trgni (lista)
  (cond 
    ((null lista) nil)
    ((not (atom (car lista))) (cons (trgni (car lista)) (trgni (cdr lista))))
    ((eql nil (car lista)) (trgni (cdr lista)))
    (t (cons (car lista) (trgni (cdr lista))))))

我的代码有一个问题,当我有一个只包含nils的子列表时,就会发生这种问题。例如:

(trgni '((NIL ((7))) (8 (9 (10 ((11))) 12)) (13 (NIL NIL))))

我的代码给了我:

((((7))) (8 (9 (10 ((11))) 12)) (13 NIL))

1 个答案:

答案 0 :(得分:1)

根据the hyperspec ()只是用于编写符号nil的替代符号,但是因为它是完全相同的对象CL在打印时只会使用一种符号。除非特定实现将其作为可配置功能,否则它不会成为替代符号。

在您的函数中,当您处理car时,您需要检查结果是否为空。像这样:

(let ((a (trgni (car lista))))
  (if (null a)
      (trgni (cdr lista))            ; don't include this null value
      (cons a (trgni (cdr lista))))) ; include since it's not null

请注意,这仅适用于'(1 (nil nil nil) 2)(1 2)等嵌套列表,但如果参数为(nil nil nil),该怎么办?然后它除了nil之外没有任何明智的价值来评估它,因为nil是空列表。