gpt4 book ai didi

lisp - 在 LISP 中更改列表的副本

转载 作者:太空宇宙 更新时间:2023-11-03 18:38:22 24 4
gpt4 key购买 nike

在 LISP 中,我有一个传递列表的函数。我想在不更改原始列表的情况下更改此列表的一个元素。通常,我会使用 copy-list 创建我将更改的列表的本地副本,但这似乎不起作用:

CL-USER> (defun test (item)
(let ((copy (copy-list item)))
(setf (nth 0 (nth 0 (nth 0 copy))) t)
(print item)
(print copy)))

CL-USER> (defparameter item `(((NIL NIL) (NIL NIL) (NIL NIL))
((NIL NIL NIL) (NIL NIL NIL))
((3 3) (NIL NIL))))

CL-USER> (test item)
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
CL-USER> item
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))

如您所见,item 的值已被 test 更改,即使我将列表复制到局部变量并更改了本地副本。这似乎是使用 nth 的症状。如果我使用 car 的单个调用而不是对 nth 的重复调用,该函数将按预期工作并且 item 在调用后保持不变.

为什么 nth 会这样,我如何才能继续使用 nth 而不改变传递给 test 的值?

我正在使用 Common Lisp。

最佳答案

简答:使用 cl:copy-tree

您可能想用 copy-tree 复制整棵树. copy-list 制作的副本只生成新的“主干”;您会得到一个新列表,但具有相同 元素。 Copy-tree 将复制构成树的所有 cons-tree 结构。

长答案:列表结构与树结构

文档中引用了此处的背景。来自 HyperSpec:

Function COPY-LIST

Only the list structure of list is copied; the elements of the resulting list are the same as the corresponding elements of the given list.

列表结构的词汇表条目很重要:

list structure n. (of a list) the set of conses that make up the list. Note that while the car component of each such cons is part of the list structure, the objects that are elements of the list (i.e., the objects that are the cars of each cons in the list) are not themselves part of its list structure, even if they are conses, except in the (circular) case where the list actually contains one of its tails as an element. (The list structure of a list is sometimes redundantly referred to as its "top-level list structure" in order to emphasize that any conses that are elements of the list are not involved.)

作为一个非常简单的例子,我们可以利用 *print-circle* 向我们展示共同子结构的事实:

CL-USER> (setf *print-circle* t)
T

CL-USER> (let ((l '((a b c) (d e f))))
(list l (copy-list l)))
;=> ((#1=(A B C) #2=(D E F)) (#1# #2#))

CL-USER> (let ((l '((a b c) (d e f))))
(list l (copy-tree l)))
;=> (((A B C) (D E F)) ((A B C) (D E F)))

copy-tree 上的 HyperSpec 条目没有链接到树结构,但是一个词汇表条目:

tree structure n. (of a tree) the set of conses that make up the tree. Note that while the car component of each such cons is part of the tree structure, the objects that are the cars of each cons in the tree are not themselves part of its tree structure unless they are also conses.

第二句话有点奇怪,但它可能只是作为 列表结构 条目的最小调整复制和粘贴而存在的。参见 my answerDefinition of tree structure in Lisp有关更多信息。

关于lisp - 在 LISP 中更改列表的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26791982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com