Lisp列表迭代

时间:2008-09-05 17:59:01

标签: lisp list iteration

我有一个获取x(值)和xs(列表)的函数,并从列表中删除大于x的所有值。好吧它不起作用,你能告诉我为什么吗?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))

6 个答案:

答案 0 :(得分:5)

我认为这条线路不对:

(setf xst (remove elem xs))))

setf的第一个参数是地点,后跟值。看起来你倒退了(xstnil或未初始化)。

您可能会发现这样做更容易:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))

答案 1 :(得分:4)

最简洁的AFAIK:

(defun bigger-elements (x xs) (remove x xs :test #'<))

返回一个新的列表,它会从xs中删除所有元素y

(< y x)

或使用着名的LOOP:

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))

答案 2 :(得分:1)

它的工作原理如下:

(defun filterBig (x xs)
  (remove-if (lambda (item) (> item x)) xs))

'#'是什么?它没有用它编译。<​​/ p>

答案 3 :(得分:1)

如果你想用Lisp Way做这个,你可以使用递归来返回新的列表:

(defun biggerElems (x xs)
  (cond ((null xs) NIL)
        ((< x (car xs))
         (biggerElems x (cdr xs)))
       (t
        (cons (car xs) (biggerElems x (cdr xs))))))

@LuísOliveira

此解决方案与问题中发布的解决方案形成鲜明对比。如果我们需要做一些稍微复杂的事情,那么建立基于操纵列表的递归方法是很重要的。

答案 4 :(得分:1)

@Ben:这不是setf调用错误 - 问题是他没有更新xs。

ie:xst被设置为xs并删除了元素,但xs没有被更新。如果要删除第二个元素,xst将返回第一个元素。

您需要将xst绑定到xs,并使用xst替换remove调用中的xs。然后,这将删除x大于的所有元素。即:

(defun biggerElems(x xs)
  (let ((xst xs))
    (dolist (elem xs)
      (when (> x elem)
        (setf xst (remove elem xst))))
    xst))

将xst设置为(copy-list xs)然后使用delete而不是remove(删除是破坏性的......可能会稍快一些......取决于你的实现,它可能比删除更快。因为你调用了这个多次,你可以获得更好的性能,复制一次列表并破坏性删除它。)

可替换地:

(defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own
  (loop for elem in xs when (<= x elem) collect elem))

回顾一下你原来的帖子,这有点令人困惑......你说你删除了大于x的所有元素,但是你的代码看起来正试图删除所有x大于的元素。我写的解决方案返回所有大于x的元素(即:删除所有元素x大于)。

答案 5 :(得分:0)

  

'#'是什么?它没有   用它编译。<​​/ p>

错字。通常情况下,您使用#'(例如(remove-if #'oddp list))来引用功能,但在我编辑时,我忘记删除“#”。