Lisp 列表迭代
我有一个函数,它获取 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您想以 Lisp 方式执行此操作,您可以使用递归来返回新列表:
@Luís Oliveira
此解决方案与问题中发布的解决方案进行对比。 如果我们需要做一些稍微复杂的事情,那么基于递归方法来操作列表就很重要。
If you want to do this the Lisp Way, you could use recursion to return the new list:
@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.
它的工作原理是这样的:
“#”是做什么用的? 它没有与它一起编译。
It worked like that:
What was the '#' for? It didn't compile with it.
最简洁的 AFAIK:
返回一个新列表,它从 xs 中删除所有元素 y
或使用著名的循环:
Most concise AFAIK:
returning a fresh list, it removes all elements y from xs for which
or using the famous LOOP:
@Ben:这不是 setf 调用是错误的 - 问题是他没有更新 xs。
即: xst 被设置为 xs 并删除了元素,但 xs 没有被更新。 如果要删除第二个元素,xst 会将第一个元素放回其中。
您需要将 xst 绑定到 xs,并将删除调用中的 xs 替换为 xst。 这将删除所有大于 x 的元素。 即:
将 xst 设置为 (copy-list xs) 然后使用删除而不是删除可能会稍快一些(删除是破坏性的......根据您的实现,它可能比删除更快。因为您多次调用此函数,复制列表一次并从中破坏性删除可能会获得更好的性能)。
或者:
回顾你原来的帖子,有点令人困惑......你说你删除了所有大于 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:
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:
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).
错字。 通常你用
#'
来引用函数(例如(remove-if #'oddp list)
),但是当我编辑时,我忘记删除'#'。Typo. Normally you refer to functions with
#'
(like(remove-if #'oddp list)
), but when I was editing, I forgot to remove the '#'.我认为这一行是不正确的:
setf
的第一个参数是位置,后面是值。 看起来你把它弄反了(并且 xst 要么是 nil 要么是未初始化)。您可能会发现这样做更容易:
I think it's this line that's not right:
The first argument to
setf
is the place, followed by the value. It looks like you have it backwards (andxst
is eithernil
or uninitialized).You might find it easier to do this: