使用列表作为参数进行defun [英] defun with a list as argument

查看:52
本文介绍了使用列表作为参数进行defun的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图选择Lisp作为我的新语言,但在解决如何使传递给它的列表的每个元素上使用函数的各个部分时遇到一些问题.

I'm trying to pick up Lisp as my new language, and I'm having some issues working out how to have parts of a function work on each element of the list passed to it.

出于学习如何解决此问题的目的,我尝试编写一种相当基本的除法形式,当列表的元素之一为0(而不是仅返回0)时,它不会崩溃.

For the purpose of learning how to get around this, I am trying to write a fairly basic form of division does not croak when one of the elements of the list are 0 (but instead just returns 0)

(defun divtest (elements)
  (dolist (x elements)
    (if (zerop x) 0 () )
  (/ elements)))))

我尝试将其运行为:

(divtest '(20 2 5))

哪个产量:

*** - /: (20 2 5) is not a number

故障点似乎源于以下事实:我在将列表中的元素传递给函数之前没有提取"列表中的元素(在这种情况下,/或dolist都无法按预期工作,因为x从不求值0). 如果我是对的,有人可以告诉我如何进行这种提取"吗?

The point of failure seems to be rooted in the fact that i am not "extracting" the elements in the list before passing them to the function (in this case, neither / nor dolist works as intended, as x never evaluates to 0). If I'm right, can someone tell me how to perform this "extraction"?

注意:此问题与我已经问过了,但是由于我不清楚先前答案的哪一部分实际上可以按预期解决此特定问题,因此我决定进一步研究基础知识

Note: This question is related to one that I've asked earlier, but as I'm unclear about which part of the previous answer actually allowed it to work as intended with this specific problem i decided to go further into the basics

推荐答案

/将一个或多个数字作为参数,但是在您的代码中却将其传递给列表-显然这是行不通的.函数apply在这里是您的朋友-(apply #'foo a b (list c d e))等效于(foo a b c d e).请注意,要使用的函数和最终列表之间的apply自变量是可选的,因此(apply #'/ '(20 2 5))等效于(/ 20 2 5).

/ takes as arguments one or more numbers, but in your code you're passing it a list - clearly this will not work. The function apply is your friend here - (apply #'foo a b (list c d e)) is equivalent to (foo a b c d e). Note the the arguments to apply between the function to use and the final list are optional, so (apply #'/ '(20 2 5)) is equivalent to (/ 20 2 5).

此外,您删除零的尝试也将不起作用. dolist正在评估参数列表elements中每个项目的主体,但是您实际上并没有做任何事情来更改elements的内容(评估dolist主体的结果不会重新分配给源)如您所愿).

Also, your attempt at removing zeros will not work. dolist is evaluating its body for each item in the argument list elements, but you're not actually doing anything to change the content of elements (the result of evaluating dolist s body is not reassigned to the source element as you seem to expect).

您正在寻找函数remove-if(及其破坏性的对等物delete-if).下面显示了如何使用它(它需要很多可选参数,您无需为此担心).

The functions remove-if (and its destructive counterpart, delete-if) are what you are looking for. The following shows how to use it (it takes lots of optional arguments, which you don't need to worry about for this purpose).

(defun divtest (elements)
  (apply #'/ (remove-if #'zerop elements)))

还请注意,如果elements列表的第一个元素为零,则此操作将无法正确执行(假设我了解该函数的用途).因此,您可能想要

Also note that this won't behave correctly if the elements list has zero as its first element (assuming I understand what the function's meant to do). So you might instead want something like

(defun divtest (elements)
  (apply #'/ (first elements) (remove-if #'zerop (rest elements))))

有关更多详细信息,请参见Hyperspec.

See the Hyperspec for more details.

这篇关于使用列表作为参数进行defun的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆