2010-05-25 83 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'等放進去,而且我們可能會在這些日子裏放入另一個循環結構。

所以我的猜測是,如果你沒有看到它,它不在那裏。