emacs - 在 Emacs Lisp 中逐步迭代列表

标签 emacs elisp slice

我在 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 中逐步返回元素?

最佳答案

这是一个简短的说明,比较使用 -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!

关于emacs - 在 Emacs Lisp 中逐步迭代列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22591728/

相关文章:

emacs - 通过 emacs shell 进行 ssh 吗?

vim - 我想改变文本在任何文本编辑器中的内部表示方式

mysql - 具有 crm 功能的命令行邮件客户端

Emacs 守护进程 : swapping keys

emacs - Emacs Elscreen-如何禁用“分屏”?

emacs - 我想在eshell中用 `ls`替换 `ls -l`

python - 将切片作为参数传递时会发生什么?

python - Emacs org-mode Python 源代码块不使用 python-mode.el 导出

python - 为什么通过切片分配到列表末尾之后不会引发 IndexError?

pointers - 为什么在本 golang 教程中将指针用于结构实例?