Lisp 列表迭代

发布于 2024-07-04 00:40:47 字数 234 浏览 6 评论 0原文

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

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

I have a function that gets x(a value) and xs(a list) and removes all values that are bigger than x from the list. Well it doesn't work, can you tell me why?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你的往事 2024-07-11 00:40:49

如果您想以 Lisp 方式执行此操作,您可以使用递归来返回新列表:

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

@Luís Oliveira

此解决方案与问题中发布的解决方案进行对比。 如果我们需要做一些稍微复杂的事情,那么基于递归方法来操作列表就很重要。

If you want to do this the Lisp Way, you could use recursion to return the new list:

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

@Luís Oliveira

This solution is to contrast with the one posted in the question. Had we needed to do something slightly more complicated it's important to be grounded in the recursive approach to manipulating lists.

云胡 2024-07-11 00:40:49

它的工作原理是这样的:

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

“#”是做什么用的? 它没有与它一起编译。

It worked like that:

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

What was the '#' for? It didn't compile with it.

∞觅青森が 2024-07-11 00:40:49

最简洁的 AFAIK:

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

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

(< y x)

或使用著名的循环:

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

Most concise AFAIK:

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

returning a fresh list, it removes all elements y from xs for which

(< y x)

or using the famous LOOP:

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))
姜生凉生 2024-07-11 00:40:49

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

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

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

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

将 xst 设置为 (copy-list xs) 然后使用删除而不是删除可能会稍快一些(删除是破坏性的......根据您的实现,它可能比删除更快。因为您多次调用此函数,复制列表一次并从中破坏性删除可能会获得更好的性能)。

或者:

(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 的元素)。

@Ben: It isn't the setf call that is wrong--the problem is that he is not updating xs.

ie: xst is being set to xs with the element removed, but xs is not being updated. If a second element is to be removed, xst will have the first back in it.

you would need to bind xst to xs, and replace the xs in the remove call with xst. This would then remove all elements x is bigger than. ie:

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

It might be slightly faster to set xst to (copy-list xs) and then use delete instead of remove (delete is destructive... depending on your implementation, it may be faster than remove. Since you are calling this multiple times, you may get better performance copying the list once and destructively deleting from it).

Alternatively:

(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))

Looking back over your original post, it is a little confusing... you say you remove all elements bigger than x, but your code looks like it is attempting to remove all elements x is bigger than. The solutions I wrote return all elements bigger than x (ie: remove all elements x is bigger than).

川水往事 2024-07-11 00:40:49

“#”是做什么用的? 它没有
用它来编译。

错字。 通常你用#'来引用函数(例如(remove-if #'oddp list)),但是当我编辑时,我忘记删除'#'。

What was the '#' for? It didn't
compile with it.

Typo. Normally you refer to functions with #' (like (remove-if #'oddp list)), but when I was editing, I forgot to remove the '#'.

一抹微笑 2024-07-11 00:40:47

我认为这一行是不正确的:

(setf xst (remove elem xs))))

setf 的第一个参数是位置,后面是值。 看起来你把它弄反了(并且 xst 要么是 nil 要么是未初始化)。

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

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

I think it's this line that's not right:

(setf xst (remove elem xs))))

The first argument to setf is the place, followed by the value. It looks like you have it backwards (and xst is either nil or uninitialized).

You might find it easier to do this:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文