List 在Lisp中复制和修改列表的标题

List 在Lisp中复制和修改列表的标题,list,lisp,sbcl,List,Lisp,Sbcl,我在学口齿不清。我希望向列表中添加一个新列表,例如((11)(0 0 0)),其中此列表集合的新头是基于以前的头计算的 以下是我在Slimv和sbcl的REPL环境中尝试的内容: > (defvar *ll* (list (list 1 1 1) (list 0 0 0))) *LL* > *ll* ((1 1 1) (0 0 0)) > (push (car *ll*) *ll*) ((1 1 1) (1 1 1) (0 0 0)) > (setf (nth 2 (ca

我在学口齿不清。我希望向列表中添加一个新列表,例如((11)(0 0 0)),其中此列表集合的新头是基于以前的头计算的

以下是我在Slimv和sbcl的REPL环境中尝试的内容:

> (defvar *ll* (list (list 1 1 1) (list 0 0 0)))
*LL*
> *ll*
((1 1 1) (0 0 0))
> (push (car *ll*) *ll*)
((1 1 1) (1 1 1) (0 0 0))
> (setf (nth 2 (car *ll*)) 2)
2
> *ll*
((1 1 2) (1 1 2) (0 0 0))
如上所示,我只想修改第一个列表的最后一个元素,但不知何故,第二个列表的最后一个元素也被修改了

我注意到,如果我进入一个全新的列表,结果会有所不同:

> (defvar *lll* (list (list 1 1 1) (list 0 0 0)))
*LLL*
> (push '(1 1 1) *lll*)
((1 1 1) (1 1 1) (0 0 0))
> (setf (nth 2 (car *lll*)) 2)
2
> *lll*
((1 1 2) (1 1 1) (0 0 0))
我想知道是什么导致了这些不同的结果,以及如何实现“将新列表添加到列表列表中,其中结果列表集合的新头是基于以前的头计算的”的结果。谢谢

(car*ll*)
(cadr*ll*)
是相同的列表 如上所示,我只想修改第一个元素的最后一个元素 列表,但不知何故,第二个列表的最后一个元素也是 变了

那里只有一个对象,你修改了它。这与您使用某种结构化数据类型(实际上,什么是cons单元格,而不是只有两个字段的结构化数据类型)没有任何区别。如果你有一个人的列表,然后你再次将第一个人添加到列表中,仍然只有一个人;此人仅出现在列表中的两个位置。如果你改变了这个人的名字,你会在两个地方看到它。如果设置为
t
,实际上可以看到共享结构

CL-USER> (defvar *ll* (list (list 1 1 1) (list 0 0 0)))
*LL*
CL-USER> *ll*
((1 1 1) (0 0 0))
CL-USER> (push (car *ll*) *ll*)
((1 1 1) (1 1 1) (0 0 0))
CL-USER> *ll*
((1 1 1) (1 1 1) (0 0 0))
CL-USER> (setf *print-circle* t)
T
CL-USER> *ll*
(#1=(1 1 1) #1# (0 0 0))
使用
#1=…
#1#
的符号表示同一对象是列表的第一个和第二个元素

如果你想要一份,就复印一份 我想在列表中添加一个新列表,比如说
((1 1)(0 0 0))
, 其中,此列表集合的新标头是基于 前任校长

> (push (car *ll*) *ll*)
((1 1 1) (1 1 1) (0 0 0))
你说你想在列表中添加一个新列表,但你没有添加一个新列表;您正在添加
(car*ll*)
,这是您在开头用
(list 1)
创建的列表。如果要复制列表,则需要显式复制,例如,使用:

不要修改文字数据! 另外,您在第二个代码块中所做的实际上是未定义的行为,因为您正在修改文本列表
'(1)


请参阅以了解更多有关此问题的原因。

谢谢,这真的很有帮助!可能重复的
> (push (car *ll*) *ll*)
((1 1 1) (1 1 1) (0 0 0))
> (push (copy-list (car *ll*)) *ll*)
((1 1 1) (1 1 1) (0 0 0))
> (defvar *lll* (list (list 1 1 1) (list 0 0 0)))
*LLL*
> (push '(1 1 1) *lll*)            ; '(1 1 1) is literal data.
((1 1 1) (1 1 1) (0 0 0))
> (setf (nth 2 (car *lll*)) 2)     ; (car *lll*) is literal data, and you're modifying it!
2
> *lll*
((1 1 2) (1 1 1) (0 0 0))