list - 为什么 mapcar 只使用从值列表返回的参数之一?

标签 list lisp common-lisp map-function

我是 Lisp 的新手,我遇到了以下问题。

我正在尝试交换多个列表中的数字并生成一个列表列表作为结果,以便每个列表中第一个数字的所有数字都将收集在一个列表中,该列表是第一个元素结果列表;并且每个列表中排名第二的所有数字将被收集在另一个列表中,该列表是结果列表的第二个元素;等等。

这是一个例子:

(foo '((3 4 2 4) (2 5 6 9) (1 -2 8 10)) ) 
=> ((3 2 1) (4 5 -2) (2 6 8) (4 9 10))

我目前的解决方案是这样的:

(defun foo (list)
    (mapcar #'list (values-list list))
)

据我所知,values-list 应该返回给定参数 list 中的所有子列表。然后 mapcar 将遍历每个子列表的每个元素并将它们制成一个列表。

第二部分有效,但是只使用了第一个子列表,导致 ((3) (4) (2) (4)) 而不是 (( 3 2 1) (4 5 -2) (2 6 8) (4 9 10))

这是为什么?

(我正在使用 CLISP)。

最佳答案

在你的代码中

(defun foo (list)
  (mapcar #'list (values-list list)))

values-list 将列表作为多个值返回。但是您调用的是像 mapcar 这样的函数,而普通的函数调用每个参数只需要一个值。

要修复它,您可以通过 multiple-value-call 调用 mapcar:

CL-USER 47 > (defun foo (list)
               (multiple-value-call #'mapcar #'list (values-list list)))
FOO

CL-USER 48 > (foo '((3 4 2 4) (2 5 6 9) (1 -2 8 10)) )
((3 2 1) (4 5 -2) (2 6 8) (4 9 10))

然后上面会将所有值传递给mapcar

请注意,参数列表在 Common Lisp 实现中是有限的。请参阅变量 call-arguments-limit。只能确定小于 call-arguments-limit 参数的函数调用在给定的 Common Lisp 实现中有效。

因此,对于具有无限长度列表的列表处理,不应依赖于 applymultiple-value-call 等功能。

使用多个值

Common Lisp 支持多值作为一种优化。它允许一个人返回多个值,而无需为其构造数据结构。

通常函数每个参数只接收单个值。

所有与多值相关的事情都是通过运算符完成的:values 返回值,multiple-value-bind 接收值并将它们绑定(bind)到变量,...然后是多值调用值列表多值限制多值列表multiple-value-setq, (setf (values ...) ...), multiple-value-prog1, nth -值

关于list - 为什么 mapcar 只使用从值列表返回的参数之一?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59307111/

相关文章:

python - 游戏几秒后崩溃

python - 子列表到字典

lisp - 通过 Scheme 的 Lapack

根据第 n 个元素对列表列表进行排序,然后是第 n+1 个元素,依此类推

python - 如何从列表列表中制作有序字典?

python - 从 txt 文件读取向量并排序

lisp - 为什么 Clojure 除了 "keywords"之外还有 "symbols"?

lisp - 在使用 eval 和 quote 函数时需要帮助

emacs - 使用 slime 时如何跳转到 emacs 中的函数定义?

macros - 使用 Lisp 宏创建类似的函数