使用lisp将变量附加到列表列表

时间:2016-09-25 20:46:03

标签: list lisp common-lisp

我有一个如下定义的列表:

(defparameter testlist '(((a b) (c d)) ((e f) (g h ))) )

我还有一个变量定义为:

(defparameter feature 'u)

我想在(c d)附加一个功能。

当我尝试:

(setf (nth 1 (nth 0 testlist)) (append (nth 1 (nth 0 testlist)) feature)) 

testlist变为:

(((A B) (C D . U)) ((E F) (G H)))

但是,我想要一个非虚线列表。

我无法弄清楚为什么会有这个结果。你能解释为什么或建议一个更好的追加方法,这对初学者来说是可以理解的吗?

1 个答案:

答案 0 :(得分:3)

首先关闭feature 列表。 append允许最后一个参数为任何内容,但如果最后一个元素本身不是正确的列表,则结果将不是正确的列表。因此:

(append '(1 2) 3)        ; ==> (1 2 . 3)
(append '(1 2) '(3 . 4)) ; ==> (1 2 3 . 4)
(append '(1 2) '(3 4))   ; ==> (1 2 3 4)

因此,如果您希望(list feature)成为要替换的列表中的一个元素而不是新的虚线值,则需要附加feature

您需要在需要重新创建之前找到要更改的列表以及所有内容,但只需与原始源共享后即可找到所有内容:

在结果可以共享cadar的同时,您需要重新设置caar时,想要更改cdr的结构:

(let ((lst '(((a b) (c d)) ((e f) (g h )))) (feature 'x))
  (list* (list (caar lst) (append (cadar lst) (list feature))) (cdr lst)))
; ==> (((a b) (c d x)) ((e f) (g h)))

现在,您如何选择使用该结果取决于您。您可以setf绑定,除了不必要的后果之外,您将具有相同的行为。