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

时间:2014-12-31 19:03:54

标签: lisp common-lisp

我创建了一个随机选择&#39;位的功能。从嵌套列表中删除,例如((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)会打印相同的内容。< / p>

(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)))))

1 个答案:

答案 0 :(得分: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