迭代一个列表并用自己的条件检查每个元素?

时间:2016-11-24 15:26:07

标签: list loops if-statement syntax common-lisp

对于家庭作业,我试图遍历列表并对我在Common Lisp中遇到的每个元素进行if语句。 我的大部分问题都来自于我不太了解语法。

以下是我要做的事情:

*lst*例如(1 4 2 6 4 7 2 4)

(setq finalList())

(loop for x in lst                      

    (if ((< x 5) && (not(equal(x nil))))       ; IF x < 5 and x != nil

         (append lst x)                        ; THEN STATEMENT

         (princ "Skip")                        ; ELSE STATMENT
     )

逻辑上应该这样做,但是,我的语法可能有问题 (如果我在这里忘记了额外的冒号,请判断是否为伪代码,谢谢)

如何遍历列表并为我遇到的每个元素制作 if else 语句?

1 个答案:

答案 0 :(得分:3)

错误

  1. 语法:代替中缀&&,您需要前缀and

  2. loopdo表单前需要关键字if

  3. append是非破坏性的,因此如果您没有将其返回值分配给变量,则不会执行任何操作。

  4. 您在(func arg1 arg2 ...)电话中使用的Lisp函数调用语法为(func (arg1 arg2 ...))而非equal

  5. 条件顺序很重要:如果xnil,则(< x 5)会发出错误信号,因此您需要在比较前检查x

  6. 漫长而复杂的(not (equal x nil))实际上相当于x

  7. 与其他语言(例如C和Python)不同,在Lisp parens中很重要,例如,foo(foo)((foo))是三个非常不同的东西,永远不会可以互换使用。

  8. 解决方案

    使用循环微语言

    loop设施非常完美,因为它有ifcollect条款:

    (loop for x in lst
       if (and x (< x 5))
       then collect x
       else (print x))
    

    注意:这看起来并不像Lisp,因此您可能希望在学习语言时避开循环。

    使用功能编程

    (remove-if-not (lambda (x) (and x (< x 5))) lst)
    

    注意:这不打印已删除的元素,我确信您无论如何都只有print子句进行调试。

    使用迭代

    (let ((res ()))
      (dolist (x lst (nreverse res))
        (when (and x (< x 5))
          (push x res))))
    

    注意:我使用nreverse:因为我们自己构建结果列表,所以没有理由不使用破坏性版本或reverse