Common lisp 如何确定列表是否为列表

Common lisp 如何确定列表是否为列表,common-lisp,Common Lisp,有没有一种简单的方法来确定一个列表是否是一个列表 我的第一次尝试: (defun alistp (list) (and (listp list) (every (lambda (c) (and (consp c) (or (atom (cdr c)) (null (cddr c)))))) l

有没有一种简单的方法来确定一个列表是否是一个列表

我的第一次尝试:

(defun alistp (list)
    (and (listp list)
         (every (lambda (c)
                    (and (consp c)
                         (or (atom (cdr c))
                             (null (cddr c))))))
                list)))
返回T表示
(alistp'((1.2)(2.3))

但是对于
(alistp'((1.(4.5.6)))则为零

有解决方案吗?

好吧,让我们看看关联列表:

协会名单。代表一个行业协会的行业列表 带值的钥匙,其中每个cons的汽车为钥匙,cdr为 与该键关联的值

鉴于此,这将是
alistp
的一个可能实现:

(defun alistp (alist)
  (and (listp alist)           ; a list
       (every #'consp alist))) ; of conses
现在,从您的代码示例中,我可以看出您可能已经能够自己实现这一点,但是您似乎有一个不同的alist定义。我假设您看到的Alist示例或多或少都是这样的:
((a.x)(b.y))
,可能是
((a.x)(b.(y z)))
,但最后一个元素是列表的虚线列表只是–一个列表,从您的示例输入中可以清楚地看出,您希望允许列表作为值。(无论如何,你为什么不呢?)

我想,您必须意识到的是,您的示例输入
((1.(4.5.6))
((1.4.5.6))
完全相同,这就是我在代码中使用列表作为其值的Alist的主要方式–至少,这是我通常编写它们的方式

现在,您似乎还想排除
nil
值,尽管它们也是列表–只有空的
()
。所以,你实际上想到的定义是这样的:

协会名单。cons单元格的列表,表示 具有非nil值的钥匙,其中每个cons的车辆为钥匙,cdr为 与该键关联的值

如果这确实是您想要的,请遵循新的定义:

(defun alistp (alist)
  (flet ((true-cdr-p (element)
           (and (consp element)        ; cons cell
                (cdr element))))       ; with non-nil cdr (i.e. value) 
    (and (listp alist)                 ; a list
         (every #'true-cdr-p alist)))) ; of cons cells with non-nil cdr

或者类似的。不过,我建议还是使用上面的简单版本。

谢谢@danlei。我知道我错过了一些明显的东西。。。我是!