我试图转置列表清单;我的评论表明了思考过程。
(setq thingie '((1 2 3) (4 5 6) (7 8 9))) ;;test case
(defun trans (mat)
(if (car mat)
(let ((top (mapcar 'car mat)) ;;slice the first row off as a list
(bottom (mapcar 'cdr mat))) ;;take the rest of the rows
(cons top (trans bottom)))) ;;cons the first-row-list with the next-row-list
mat)
(trans thingie)
=> ((1 2 3) (4 5 6) (7 8 9)) ;;wait what?
但是,我真的希望它是
((1 4 7) (2 5 8) (3 6 9))
我做错了什么?
答案 0 :(得分:25)
有一种简单的方法:
(defun rotate (list-of-lists)
(apply #'mapcar #'list list-of-lists))
您的尝试始终返回原始mat
。修复缩进,您会发现if
表单中返回的值总是被丢弃。
编辑:如何运作:
List
接受任意数量的参数并列出它。它的功能定义可以这样设想:
(defun list (&rest arguments)
arguments) ; exploit the automatic &rest construction
Mapcar
获取一个函数和任意数量的列表,然后创建一个
通过调用函数创建的值的新列表
这些清单中的一个要素。示例:(mapcar #'foo '((A B) (C
D)))
将构造一个新列表,其中第一个元素是
结果为(foo 'A 'C)
,第二个结果为(foo 'B 'D)
。
Apply
将可扩展参数列表指示符作为最后一个
论点。这意味着如果你给它一个列表作为它的最后一个
参数,该列表可以“传播”以产生单个参数
为功能。示例:(apply #'+ '(1 2 3))
具有相同的功能
效果为(+ 1 2 3)
。
现在你可以扩展这一行:
(apply #'mapcar #'list '((A B) (C D)))
=>
(mapcar #'list '(A B) '(C D))
=>
(list (list 'A 'C) (list 'B 'D))
=>
'((A C) (B D))