在Common Lisp中转置列表 [英] Transposing lists in Common Lisp

查看:95
本文介绍了在Common Lisp中转置列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试转置列表列表;我的评论表明了思考过程.

I am trying to transpose a list of lists; my comments indicate the thought process.

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

但是,我真的希望它成为

But, I really want it to be

((1 4 7) (2 5 8) (3 6 9))

我做错了什么?

推荐答案

有一个简单的方法:

(defun rotate (list-of-lists)
  (apply #'mapcar #'list list-of-lists))

您的尝试总是返回原始的mat.修正缩进后,您会发现总是抛弃了if表单的返回值.

Your attempt is always returning the original mat. Fix your indentation, and you see that the returned value from the if form is always thrown away.

工作原理:

  • List接受任意数量的参数并列出其列表.其功能定义可以想象如下:

  • List takes any number of arguments and makes a list of it. Its function definition can be imagined about like this:

(defun list (&rest arguments)
  arguments) ; exploit the automatic &rest construction

  • Mapcar接受一个函数和任意数量的列表,然后使 通过始终调用函数创建的值的新列表 这些列表中的一个元素.示例:(mapcar #'foo '((A B) (C D)))将构造一个新列表,其中第一个元素是 (foo 'A 'C)的结果,第二个是(foo 'B 'D)的结果.

  • Mapcar takes a function and any number of lists, and then makes a new list of the values created by calling the function always with one element from those lists. Example: (mapcar #'foo '((A B) (C D))) will construct a new list, where the first element is the result of (foo 'A 'C) and the second the result of (foo 'B 'D).

    Apply将可扩展参数列表指示符作为最后一个 争论.这意味着,如果您给它一个列表作为最后一个 参数,该列表可以扩展"以产生单个参数 为功能.示例:(apply #'+ '(1 2 3))具有相同的 效果为(+ 1 2 3).

    Apply takes a spreadable argument list designator as its last argument. This means that if you give it a list as its last argument, that list can be "spread" to produce individual arguments for the function. Example: (apply #'+ '(1 2 3)) has the same effect as (+ 1 2 3).

    现在您可以展开以下行:

    Now you can expand the line:

    (apply #'mapcar #'list '((A B) (C D)))
    

    =>

    (mapcar #'list '(A B) '(C D))
    

    =>

    (list (list 'A 'C) (list 'B 'D))
    

    =>

    '((A C) (B D))
    

    这篇关于在Common Lisp中转置列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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