讨论操作list的各种处理 push append等


#1

创建list

(setq load-path-list
       '("~/.emacs.d/customs"
         "~/.emacs.d/download"
         "~/.emacs.d/common"))

目的,把load-path-list加入load-path

写法一(用push,迭代式):

(dolist (path load-path-list) (push path load-path))

写法二(用push,函数式):

(mapcar (lambda (path) (push path load-path)) load-path-list)

写法三(用append):

(setq load-path (append load-path load-path-list)) 

push是破坏性函数,可以直接修改load-path指向的list。而append对list没有破坏性,所以得用setq从新把append的返回值赋值给load-path

有没有直接把一个list的内容加入到另一个list中,而不产生一个新list的函数?


#2

nconc


你也搜索一下,虽然Emacs的确用的人少

ELISP> (setq a '(3))
(3)

ELISP> (nconc a '(4))
(3 4)

ELISP> a
(3 4)

https://www.emacswiki.org/emacs/DestructiveOperations


#3

学习了

勉強なりました


#4

Emacs Lisp Manual 中提到的「破坏性」(Destructively / Destructive)指会修改 List 结构的操作,push 并没有没有破坏性,因为它不会修改任何既有 List 的结构:

(push path load-path)
;; 展开
(setq load-path (cons path load-path))

append 也没有破坏性,因为它虽然必须修改列表的结构,但它事先做了必要的拷贝:

(append list1 list2)
;; 有一些类似于
(nconc (copy-sequence list1) list2)

此外,破坏性不等于 In-place 地修改参数,常常还是要依赖于返回值,所以得用 (setq foo (... foo ...))


#5

哦,原来push也用的是setq

补充一下,nconc是尾插法,有对应的头插法吗?我也在搜一下去


#6

没有,这几天有个帖子说的就是这个,你翻翻就能看到,我手机就不找链接了


#7

c o n s


#8

cons是追加一个元素,而不是追加一个列表里的所以元素,cons会把要加入的列表当做一个元素对待

(cons '(a b c) '(1 2 3)) ;; => ((a b c) 1 2 3) 而不是 (a b c 1 2 3)

#9

你每次都回得这么简短说 话 带 空 格,别人很难完全理解

== 我对空格没意见,我觉得他加空格是为了补全字数,还有你应该在下面回复,这么改我帖子好像是我说的一样 @ldbeth

ldbeth是为了不歪楼才改的,说明一下


#10

我只是来搞笑的

没有幽默感啊

抱歉!

学会无视啊!

另外说明一下,我回的短是因为觉得问题有点简单或是超出了我的能力范围亦或是我觉得意义不大还有就是很有意义想顶一下帖子。

艾特 管理员 歪楼了 还算有情可原的吧

点到为止


#11

就你的这个例子,当然是 append (即写法三)最合适了。` 也行,不过实际用的还是 append

(let ((lst '(1 2 3))
      (temp '(4 5 6)))
  `(,@lst ,@temp))
;; => (1 2 3 4 5 6)

;;; 等价于

(let ((lst '(1 2 3))
      (temp '(4 5 6)))
  (append lst temp))
;; => (1 2 3 4 5 6)