Lisp:如何停止不需要的多个列表变量的重新分配
Lisp: How to stop unwanted reassignment of multiple list variables
在 lisp 中,我有以下示例代码:
(setf list1 '("a" "b" "c" ))
(setf list2 '())
(setf list2 list1)
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
我想要的结果是:
(a b d)(a b c)
但它重新分配了 'list1' 和 'list2' 的第 n 个元素,导致:
(a b d)(a b d)
我假设这是因为我在代码的前面将 list2 设置为等于 list1,但通常当您将变量设置为彼此相等时,它们不会那样改变。这里发生了什么?
万一没人能帮我,我想出了一个解决方案来解决这个问题,虽然它不是很优雅:
(setq list1 '("a" "b" "c"))
(setq list2 '())
(setq i 0)
(loop
(setf list2 (append list2'(0)))
(setf (nth i list2)(nth i list1))
(setq i (+ i 1))
(when (= i (list-length list1)) (return)))
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
还是很好奇为什么(setf (nth N L) T)
会重置所有已经用set
相等的列表的第n个元素。
当您在 lisp 中分配列表时,不会发生复制。您问题的第三行:
(setf list2 list1)
不复制列表,而是将 list2 设置为也引用与 list1 相同的 cons 单元格。如果您想要一个新列表,请改用 copy-list:
(setf list2 (copy-list list1))
这会将 list2 设置为 list1 的浅表副本;也就是说list1和list2中CONS单元格的所有CAR都是same.
在 lisp 中,我有以下示例代码:
(setf list1 '("a" "b" "c" ))
(setf list2 '())
(setf list2 list1)
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
我想要的结果是:
(a b d)(a b c)
但它重新分配了 'list1' 和 'list2' 的第 n 个元素,导致:
(a b d)(a b d)
我假设这是因为我在代码的前面将 list2 设置为等于 list1,但通常当您将变量设置为彼此相等时,它们不会那样改变。这里发生了什么?
万一没人能帮我,我想出了一个解决方案来解决这个问题,虽然它不是很优雅:
(setq list1 '("a" "b" "c"))
(setq list2 '())
(setq i 0)
(loop
(setf list2 (append list2'(0)))
(setf (nth i list2)(nth i list1))
(setq i (+ i 1))
(when (= i (list-length list1)) (return)))
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
还是很好奇为什么(setf (nth N L) T)
会重置所有已经用set
相等的列表的第n个元素。
当您在 lisp 中分配列表时,不会发生复制。您问题的第三行:
(setf list2 list1)
不复制列表,而是将 list2 设置为也引用与 list1 相同的 cons 单元格。如果您想要一个新列表,请改用 copy-list:
(setf list2 (copy-list list1))
这会将 list2 设置为 list1 的浅表副本;也就是说list1和list2中CONS单元格的所有CAR都是same.