代码之家  ›  专栏  ›  技术社区  ›  hatmatrix

在(emacs)lisp中提取/切片/重新排序列表?

  •  6
  • hatmatrix  · 技术社区  · 14 年前

    在python中,您可能会做一些类似的事情

    i = (0, 3, 2)
    x = [x+1 for x in range(0,5)]
    operator.itemgetter(*i)(x)
    

    得到 (1, 4, 3) . 在(emacs)lisp中,我编写了一个名为extract的函数,它执行类似的操作,

    (defun extract (elems seq)
      (mapcar (lambda (x) (nth x seq)) elems))
    
    (extract '(0 3 2) (number-sequence 1 5))
    

    但我觉得应该有内置的东西?我所知道的只是 first, last, rest, nth, car, cdr …怎么走?~提前谢谢。~

    3 回复  |  直到 14 年前
        1
  •  4
  •   6502    14 年前

    如果您的问题是速度,那么使用(向量1、2、3、4、5)而不是列表,以及(aref vec index)来获取元素。

    (defun extract (elems seq)
      (let ((av (vconcat seq)))
        (mapcar (lambda (x) (aref av x)) elems)))
    

    如果你要多次从同一个序列中提取,那么将序列存储在一个向量中就很有意义了。 python列表实际上是一维数组,在lisp中等价的是向量。

        2
  •  2
  •   Nathan Shively-Sanders    14 年前

    我只在elisp中做过简单的脚本,但它是一种相对较小的语言。和 extract 是链表上一个非常低效的函数,它是EmacsLisp中的默认数据结构。所以它不太可能是内置的。

    你的解决方案是最简单的。它是n^2,但要使其更快,需要更多的代码。

    下面是一个关于它可能如何工作的猜测,但它也可能是完全没有根据的:

    1. 分类 elems (n log n)
    2. 创建映射已排序元素的映射 elem 原始的索引 ELEM (可能n个日志n,可能n个)
    3. 迭代通过 seq 排序 ELEM . 只保留索引的排序 ELEM (可能是n,也可能是n log n,这取决于它是哈希图还是树图)
    4. 按的值对结果排序 ELEM 映射(n log n)
        3
  •  1
  •   Ken    14 年前

    My Lisp Experiences and the Development of GNU Emacs :

    在那时候,1985年,有人拥有一台没有虚拟内存的兆字节机器。他们希望能够使用GNU Emacs。这意味着我必须尽可能地保持程序的小规模。

    例如,当时唯一的循环结构是__而__,这非常简单。无法跳出__语句,而__语句,您只需执行catch和throw,或测试运行循环的变量。这表明我一直在努力保持小规模。我们没有caar和cadr等;_挤出一切可能的是GNU Emacs的精神,Emacs Lisp的精神,从一开始。

    显然,机器现在更大了,我们不再这样做了。我们放了__caar_和_cadr_,等等,我们可能在这些天中的某一天放了另一个循环结构。

    所以我的猜测是,如果你看不到它,它就不在那里。