尽管创建了副本,但对lisp函数的参数已更改

the*_*bda 2 lisp common-lisp

我创建了一个函数来从嵌套列表中随机选择一个"位",例如,((1 0 0 1) (1 1 1 1) (0 1 0 1))然后翻转它.如果是一个,则将其设为零,反之亦然.该函数运行良好,但我发现尽管我复制了它,它仍会改变原始参数.这是函数,最后两个写入演示了这个问题.如果我((1 1 1 1))转到这个,我希望看到这个原始值打印,(write DNA-seq)但原来是修改,所以(write DNA-seq)(write CDNA-seq)打印相同的东西.

(defun rand-mutate (DNA-seq)
  (let ((CDNA-seq (copy-list DNA-seq)))
    (let ((gene (random-range 0 (length CDNA-seq))))
      (let ((base (random-range 0 (length (nth gene CDNA-seq)))))
        (cond ((= (nth base (nth gene CDNA-seq)) 0) (setf (nth base (nth gene CDNA-seq)) 1))
              (t (setf (nth base (nth gene CDNA-seq)) 0))) (write DNA-seq)(write CDNA-seq)))))
Run Code Online (Sandbox Code Playgroud)

Bar*_*mar 8

copy-list是一个浅表副本,它只复制最外面的列表,而不是每个元素引用的列表.使用copy-tree进行拷贝.

(defvar list '((1 0 0 1)))
(defvar list-copy (copy-list list))
(defvar list-copy-tree (copy-tree list))
(eq list list-copy) => NIL
(eq (car list) (car list-copy)) => T
(eq (car list) (car list-copy-tree)) => NIL
Run Code Online (Sandbox Code Playgroud)