1

我有一个 nil 列表(NIL NIL NIL NIL),我需要添加两个 X 来代替前两个 NIL,所以它变成(XX NIL NIL)

我有以下代码:

(cons x (cons x (cons (cdr '(NIL NIL NIL NIL))nil)))

但是这样它就会返回

(X X (NIL NIL))

那些parenteses需要删除,我不知道如何。有人能帮我吗?谢谢

4

2 回答 2

3
(list* X X (nthcdr 2 your-list))

函数 NTHCDR 返回删除了两个第一个元素的列表,函数 LIST* 返回一个新列表,在前面附加了指定的项目。请注意,您因此获得了一个新列表,而不是修改原始列表。如果您真的想修改原始列表(这很可能是个坏主意,请谨慎操作),您可以进行分配:

(setf (first your-list) 'X)
(setf (second your-list) 'X)

像这样修改列表可能会导致修改看似无关的数据。无论如何,它与引用的文字列表不兼容。

于 2017-11-29T22:56:52.977 回答
3

如果将列表传递给 的第一个参数,cons那么您将创建一个嵌套列表。首先假设我们制作了您的初始列表和符号x变量:

(defparameter *nils* '(nil nil nil nil))
*nils* ; ==> (nil nil nil nil)

(defparameter *x* 'x)
*x* ; ==> x

那么我们如何先去掉这两个。好吧,我们可以删除一个,(cdr *nils*)这意味着我们可以做两次:

(cdr (cdr *nils*))
; ==> (nil nil)

实际上不止一个carcdr访问器有多达 5 种组合的速记。速记只是以 c 开头并执行 a/d 并以 r 结尾,如下所示:

(cddr *nils*)
; ==> (nil nil)

Goodie,我们如何*x*在前面添加?Wellcons被定义为在第二个参数前面创建一个元素,因此(cons *x* (cddr *nils*)) will make(x nil nil) . Again if you want to have anotherx ` 在前面你对第一个结果做同样的事情:

(cons *x* (cons *x* (cddr *nils*)))
; ==> (x x nil nil)

使用list*就像嵌套的缺点,最后有一个尾巴。因此上面的代码可以替换为:

(list* *x* *x* (cddr *nils*))
; ==> (x x nil nil)

现在将变量替换为存储为它们的值的表达式(替换方法):

(list* 'x 'x (cddr '(nil nil nil nil)))
; ==> (x x nil nil)
于 2017-11-29T22:58:21.633 回答