替换Common Lisp列表中的项目?

时间:2008-10-04 20:08:44

标签: list lisp replace common-lisp

我有一个列表(我称之为L),索引(N)和新事物(NEW)。如果我想用N替换L中的L,那么最好的方法是什么?我应该将子列表最多N,从N到列表的末尾,然后使用列表将第一部分,NEW和最后部分的新列表粘合在一起?或者有更好的方法吗?

10 个答案:

答案 0 :(得分:25)

(setf (nth N L) NEW)

应该这样做。

答案 1 :(得分:8)

你多久会这样做;如果你真的想要一个数组,你应该使用array。否则,是的,一个函数使得包含前N个元素,新元素和尾部的副本的新列表都可以。我不知道我的头顶内置,但我有一段时间没有用Lisp编程。

这是Scheme中的解决方案(因为我知道它比Common Lisp更好,并且有一个解释器来检查我的工作):

(define (replace-nth list n elem)
  (cond
    ((null? list) ())
    ((eq? n 0) (cons elem (cdr list)))
    (#t (cons (car list) (replace-nth (cdr list) (- n 1) elem)))))

答案 2 :(得分:6)

(setf (nth N L) T)

是最清晰,最简洁,最快捷的方式,如果您想要做的是“破坏性”修改,即实际更改现有列表。它没有分配任何新内存。

答案 3 :(得分:4)

我只是尝试修复hazzen的代码:

(define (replace-nth list n elem)
  (cond 
    ((null? list) ())
    ((eq? n 0) (cons elem list))
    (#t (cons(car list) (replace-nth (cdr list) (- n 1) elem)))))

> (replace-nth (list 3 2 9 2) 2 8)
(3 2 8 9 2)

此代码在列表中插入了新元素。如果我们想要替换元素:

(define (replace-nth list n elem)
  (cond 
    ((null? list) ())
    ((eq? n 0) (cons elem (cdr list)))
    (#t (cons(car list) (replace-nth (cdr list) (- n 1) elem)))))

> (replace-nth (list 3 2 9 2) 2 8)
(3 2 8 2)

0< = n< = length(list) - 1

答案 4 :(得分:3)

hazzen的建议很好(使用数组),因为你可能想要做很多这些破坏性的更新,而且列表在随机访问时非常低效。最简单的方法

(setq A (make-array 5) :initial-contents '(4 3 0 2 1))
(setf (elt 2 A) 'not-a-number)

其中A是一个数组(尽管elt适用于任何序列)。

但是,如果必须正常运行,那就是

  1. 您想要保留旧列表和新列表
  2. 您希望新旧分享尽可能多的内存。
  3. 然后你应该使用Common Lisp相当于hazzen的代码:

    (defun replace1 (list n elem)
      (cond
        ((null list) ())
        ((= n 0) (cons elem list))
        (t (cons (car list) (replace1 (cdr list) (1- n) elem)))))
    

    这看起来很慢,因为它是,这可能就是为什么它不包含在标准中。

    hazzen的代码是Scheme版本,这很有用,就是你正在使用的。

答案 5 :(得分:1)

答案 6 :(得分:1)

使用[REPLACE] [1](我使用X代替你的T,因为T是Lisp中的真值):

(replace L (list X) :start1 N)

[1]:http://www.lispworks.com/documentation/HyperSpec/Body/f_replac.htm替换

答案 7 :(得分:1)

很快就可以在list-replace

上使用JS来完成

答案 8 :(得分:0)

显而易见的解决方案是缓慢并使用内存,正如其他人所指出的那样。如果可能,您应该尝试推迟替换元素,直到您需要在列表上执行另一个按元素操作,例如(loop for x in list do ...)

这样,你就可以分摊(内存)和迭代(cpu)。

答案 9 :(得分:-1)

(defun replace-nth-from-list  (list n elem)  
      (cond  
        ((null list) ())  
        (t (append (subseq list 0 n) elem (subseq list (+ 1 n)(length list))))))