首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Emacs Lisp中逐步迭代列表

在Emacs Lisp中逐步迭代列表
EN

Stack Overflow用户
提问于 2014-03-23 13:48:22
回答 2查看 1.5K关注 0票数 7

我在Elisp有一份名单。如何从第一开始返回由每个第n个元素组成的列表?在Python中,我使用了片表示法:

代码语言:javascript
复制
>>> range(10)[::3]
[0, 3, 6, 9]

我在dash.el列表API中找不到任何有用的东西,所以我用 macro编写了解决方案

代码语言:javascript
复制
(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中逐步返回元素?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-04 11:16:05

dash包的slice支持版本2.7中的步骤。因此,Python的range(10)[1:7:2]相当于:

代码语言:javascript
复制
(-slice (number-sequence 0 9) 1 7 2) ; (1 3 5)
票数 5
EN

Stack Overflow用户

发布于 2014-03-24 16:52:24

下面是一个简短的例子,比较循环中使用-partial和普通lambda的情况:

代码语言:javascript
复制
(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倍的性能差异,有利于一个普通的蓝宝石!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22591728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档