2010-05-25 39 views
6

在Python中,你可以做这样的事情在(emacs)lisp中提取/切片/重新排列列表?

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

得到(1, 4, 3)。 在(emacs的)口齿不清,我写了这个函数调用提取物有类似的功能,

(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 ...要走什么路? 〜提前致谢〜

回答

4

如果你的问题是速度,然后使用(矢量1 2 3 4 5)而不是一个列表,并且(aref vec索引)来获取元素。

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

如果你打算从相同的序列中提取很多次,当然有必要将序列存储在一个向量中。Python列表确实是一维数组,LISP中的等价物是向量。

+0

不知道。所以对于这个问题,我必须决定创建一个向量的开销是否值得恒定时间访问的额外开销。 – hatmatrix 2010-05-26 05:16:36

2

我只在elisp上做过简单的脚本,但它是一种相对较小的语言。并且extract在链接列表上是非常低效的功能,这是emacs lisp中的默认数据结构。所以它不太可能是内置的。

您的解决方案是最直接的解决方案。这是n^2,但为了让它更快需要更多的代码。

下面是它可能是如何工作的一个猜测,但它也可能是完全关闭基地:

  1. 排序elems(N log n)的
  2. 创建地图,在排序elem映射元素,其指数在原elem(可能是n日志n,也许n)
  3. 遍历seq和排序elem。只能存放在排序elem(可能是N,也许N日志N,取决于它是否是一个哈希表或树地图)
  4. 排序结果由elem映射。值(n log n)的指数
+0

太好了 - 谢谢你... – hatmatrix 2010-05-26 05:11:50

1

My Lisp Experiences and the Development of GNU Emacs

共有人在那些日子里,在1985年,谁有一兆机,而虚拟内存。他们希望能够使用GNU Emacs。这意味着我必须尽可能缩小程序。

例如,当时唯一的循环构造是'while',这非常简单。没有办法摆脱'while'语句,你只需要做一个catch和throw,或者测试一个运行循环的变量。这表明我在多大程度上努力保持小规模。我们没有'caar'和'cadr'等等; “挤出一切可能”是Emacs Lisp的精神,从一开始就是GNU Emacs的精神。

显然,机器现在变大了,我们不再这样做了。我们把'caar'和'cadr'等放进去,而且我们可能会在这些日子里放入另一个循环结构。

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