List 用Lisp中的defun重写列表

List 用Lisp中的defun重写列表,list,loops,lisp,List,Loops,Lisp,我想写一个输出列表的函数。 函数获取一个列表并输出一个新列表。例如: (0 0 1 2 2 1) -> (3 4 4 5 5 6)). 它所做的是:初始列表中的索引+1是新列表中的一个值。根据初始列表中的值,该值在新列表中放置x次 (1 2) -> (1 2 2) (0 3 0 3) -> (2 2 2 4 4 4) 因此3位于第二个位置,值为3,因此2(第二个位置)在新列表中放置了3次 我想出了这个,但不管用 (defun change-list (list) (se

我想写一个输出列表的函数。 函数获取一个列表并输出一个新列表。例如:

(0 0 1 2 2 1) -> (3 4 4 5 5 6)).
它所做的是:初始列表中的索引+1是新列表中的一个值。根据初始列表中的值,该值在新列表中放置x次

(1 2) -> (1 2 2)
(0 3 0 3) -> (2 2 2 4 4 4)
因此3位于第二个位置,值为3,因此2(第二个位置)在新列表中放置了3次

我想出了这个,但不管用

(defun change-list (list)
  (setq newlist '(1 2 3))
  (setq i 0) 
  (while (<= i (length list)) 
    (if (= (nth i list) 0)
      (concatenate 'list '0 'newlist)
    (concatenate 'list '(i) 'newlist))
    (+ i 1)
    (remove 0 newlist)))

这是一个更大的任务的一部分,我们没有得到太多关于lisp的教育,更像是:用lisp来做。

假设这是常见的lisp,我将在代码中列出一些问题:

(defun change-list (list)
  (setq newlist '(1 2 3))
SETQ
不声明变量,它只是设置变量

  (setq i 0) 
  (while (<= i (length list)) 
0
不是一个列表。因此,您无法将其连接起来。
串联
没有副作用。你在这里所做的一切都失去了意义。
NEWLIST
这里是一个符号,不是列表。不起作用

      (concatenate 'list '(i) 'newlist))
    (+ i 1)
i
在这里不是变量。把它放在一个列表中不会有任何影响。
串联
没有副作用。你在这里所做的一切都失去了意义。
NEWLIST
这里是一个符号,不是列表。不起作用

      (concatenate 'list '(i) 'newlist))
    (+ i 1)
上述影响已失去

    (remove 0 newlist)
    ))
上述影响已失去

    (remove 0 newlist)
    ))

您可以简化此问题的答案:

(defun change-list (list) 
  (loop for i in list and j from 1
        append (loop repeat i collect j)))

基本上,这只是做同样事情的另一种方式:

(defun change-list (x)
  (let ((index 0))
    (mapcon
     #'(lambda (y)
         (incf index)
         (let ((z (car y)))
           (unless (zerop z)
             (make-list z :initial-element index)))) x)))

但是可能对学习有用/谁知道你的教授期望什么。

我认为lisp的全部要点是,你可以不用做作业(set、setq等)。作业使事情更难推理,所以只在有好处的地方使用它。你不需要为这个问题分配任务。不使用赋值重写。我建议在你尝试编程之前先学习一些你正在使用的Lisp方言的基础知识。每一个基础语言介绍都会告诉你如何定义局部变量。如果你看麻省理工学院关于lisp的讲座,那么在介绍作业时,这是第5课,共10课。直到那时才需要它。到那时为止,他们已经介绍了一些非常复杂的东西。包括多态性。请参见:学习lisp,甚至只是为了更好地学习编程。