我在Elisp中有一个列表。如何从第1个开始返回包含每个第n个元素的列表?在Python中我有切片表示法:
>>> range(10)[::3]
[0, 3, 6, 9]
我在dash.el
列表API中找不到任何有用的内容,所以我使用loop
macro编写了我的解决方案:
(defun step (n xs)
(loop for x in xs by (lambda (xs) (nthcdr n xs))
collect x))
ELISP> (step 3 (number-sequence 0 10))
(0 3 6 9)
顺便说一句,(lambda (xs) (nthcdr n xs))
可以使用dash.el
的部分申请函数-partial
重写:(-partial 'nthcdr n)
。
loop
宏似乎有点矫枉过正。我如何在Emacs Lisp中逐步返回元素?
答案 0 :(得分:3)
这是一个简短的插图,比较使用-partial
和循环中的普通lambda:
(require 'cl-lib)
(prog1 nil
(setq bigdata (number-sequence 1 10000)))
(defun every-nth-1 (n xs)
(cl-loop for x in xs by (lambda (xs) (nthcdr n xs))
collect x))
(defun every-nth-2 (n xs)
(cl-loop for x in xs by (-partial 'nthcdr n)
collect x))
(defmacro util-timeit (expr)
(let ((t-beg (float-time))
(res (dotimes (i 1000)
(eval expr)))
(t-end (float-time)))
(/
(- t-end t-beg)
1000)))
(setq time1
(util-timeit
(length (every-nth-1 3 bigdata))))
(setq time2
(util-timeit
(every-nth-2 3 bigdata)))
(message "%s" (/ time2 time1))
调用eval-buffer
会给我一个大约4的结果。这意味着
(lambda (xs) (nthcdr n xs))
比(-partial 'nthcdr n)
快4倍,
至少没有字节编译。
通过字节编译,它在性能上给出了惊人的12.2-13.6倍的差异 赞成平原的lambda!
答案 1 :(得分:2)