Lisp 尝试返回当前列表中偶数位置的值列表

Lisp 尝试返回当前列表中偶数位置的值列表,lisp,common-lisp,Lisp,Common Lisp,这里的目标是向函数传递一个列表,并让它返回一个列表,其中的值位于前一个列表中的偶数位置 例如,返回evens'(1 2 3)=>(2),返回evens'()=>() 我终于创建了这个函数,但它只有在输入0-3个值时才起作用。当我输入0或1个值时,它只返回“NIL”,而不是返回“()” 我如何才能让它处理3个以上的值,如何返回它,使它以列表的形式打印出来,并用括号括起来 (defun return-evens (lst) (let ((return-list ()) (i 1))

这里的目标是向函数传递一个列表,并让它返回一个列表,其中的值位于前一个列表中的偶数位置

例如,返回evens'(1 2 3)=>(2),返回evens'()=>()

我终于创建了这个函数,但它只有在输入0-3个值时才起作用。当我输入0或1个值时,它只返回“NIL”,而不是返回“()”

我如何才能让它处理3个以上的值,如何返回它,使它以列表的形式打印出来,并用括号括起来

(defun return-evens (lst)
    (let ((return-list ()) (i 1))
    (loop for x in lst
        while (numberp x)
            do (if (= (mod i 2) 0)
                    (setf return-list (append return-list x))
                    ()
                    )
            do (setq i (1+ i))
            finally (return  return-list))))

对代码的一些反馈

第一个大问题:它没有正确缩进

(defun return-evens (lst)          ; in Lisp you can call it list instead of lst
                                   ; return is not a useful prefix.
                                   ; Every function returns something

    (let ((return-list ()) (i 1))  ; LOOP can return lists and iterate.
                                   ; No need for this at all.

    (loop for x in lst

        while (numberp x)   ; why this test? Are there non-numbers in the list?

            do (if (= (mod i 2) 0)   ; Lisp has a function EVENP
                                     ; but generally it is not necessary

                    (setf return-list (append return-list x))
                            ; never append to the end. Never ever.
                            ; Let LOOP collect a list, don't do it this way

                    ()
                    )

            do (setq i (1+ i))  ; iterating manually is not necessary
                                ; that's what LOOP is for

            finally (return  return-list))))
                    ; if you would let LOOP do the work, no RETURN necessary
一个更简单的解决方案:

(defun elements-at-even-positions (list)
  (loop for element in list
        for even-position = nil then (not even-position)
        when even-position collect element))

对代码的一些反馈

第一个大问题:它没有正确缩进

(defun return-evens (lst)          ; in Lisp you can call it list instead of lst
                                   ; return is not a useful prefix.
                                   ; Every function returns something

    (let ((return-list ()) (i 1))  ; LOOP can return lists and iterate.
                                   ; No need for this at all.

    (loop for x in lst

        while (numberp x)   ; why this test? Are there non-numbers in the list?

            do (if (= (mod i 2) 0)   ; Lisp has a function EVENP
                                     ; but generally it is not necessary

                    (setf return-list (append return-list x))
                            ; never append to the end. Never ever.
                            ; Let LOOP collect a list, don't do it this way

                    ()
                    )

            do (setq i (1+ i))  ; iterating manually is not necessary
                                ; that's what LOOP is for

            finally (return  return-list))))
                    ; if you would let LOOP do the work, no RETURN necessary
一个更简单的解决方案:

(defun elements-at-even-positions (list)
  (loop for element in list
        for even-position = nil then (not even-position)
        when even-position collect element))

一个简单的解决方案是通过#'cddr收集x来实现
(x in循环(cdrlst)
。这非常有效!谢谢这里一个可能的问题是,你可能会惊讶于:(位置1’(1 2 3))我不是说这是一个诡辩:如果这是给别人的,他们可能会有同样的想法。
Nil
()
是一样的:<当
*print pretty*
为真且启用了打印机转义时,code>nil可能会被打印为
()
。一个简单的解决方案是
(通过#'cddr收集x循环x in(cdr lst)
。这非常有效!谢谢这里一个可能的问题是,你可能会惊讶于:(位置1’(1 2 3))我不是说这是一个诡辩:如果这是给别人的,他们可能会有同样的想法。
Nil
()
是一样的:<当
*print pretty*
为真且启用了打印机转义时,code>nil可能被打印为
()
。或者
(循环:for元素:in(rest列表):by#'cddr:collect元素)
。或者
(循环:for元素:in(rest列表):by#'cddr:collect元素)