如何串联两个清单?


15

抱歉,但是elisp不是我最好的。我需要以这种方式组合两个字符串列表:

("a" "b" "c") + ("d" "e" "f") -> ("a" "b" "c" "d" "e" "f")

好吧,顺序并不重要,因此我编写了以下代码:

(while lista
  (add-to-list 'listb (car lista)) 
  (setq lista (cdr lista)))

它可以工作,但是我想知道是否已经有一个函数可以做到这一点。

有什么线索吗?提前致谢。


4
请参阅《 Elisp》手册的“ 节点构建列表 ”。
提请

2
append是这里的正确答案,但是另一种(破坏性的)方法是(setcdr (last a) b)
肖恩·阿雷德

1
在清单上工作?dash.el(-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince'5

切勿add-to-list在Lisp代码中使用(它在docstring中说明了这一点)。而是使用push
拉登·罗斯伯勒

Answers:


25

您也可以只使用附加。

(append '("a" "b" "c") '("d" "e" "f"))

2
而且(nconc '("a" "b" "c") '("d" "e" "f"))
律师名单

1
哦,是的,append这里的确更好。
JeanPierre

nconc可以工作,但是,如果将列表存储在变量中,则它们将被nconc修改。例如(让(((a'(1 2 3))(b'(3 4 5)))(nconc ab)a)将修改a变量。
约翰·基钦

1
FYI 在TYPE 为时cl-concatenate使用,因此两个答案都产生相同的结果。appendlist
菲尔斯(Phils)

是的,它确实可以完成这项工作。非常感谢大家的帮助。
丹尼尔(Daniele)

3

concatenate是'cl.el'中'cl-concatenate'的别名。

(连接TYPE SEQUENCE ...)

将参数SEQUENCEs连接到TYPE类型的序列中。

所以对于你的例子

(concatenate 'list '("a" "b" "c") '("d" "e" "f"))

由于它是在其中定义的,因此cl您可能必须(require 'cl)首先使用cl-concatenate它,否则可以使用默认情况下似乎已加载的内容。

此外,正如@phils指出的那样,当TYPE 为时cl-concatenate仅调用,这是来自的源:append'listcl-extra.el

(defun cl-concatenate (type &rest sequences)
  "Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
\n(fn TYPE SEQUENCE...)"
  (pcase type
    (`vector (apply #'vconcat sequences))
    (`string (apply #'concat sequences))
    (`list (apply #'append (append sequences '(nil))))
    (_ (error "Not a sequence type name: %S" type))))

因此,如果仅使用列表,则直接使用会更简单append,如@John Kitchin指出的那样。

最后,@lawlist提到了nconc

nconc是“ C源代码”中的内置函数。

(nconc和其余列表)

通过更改列表来串联任意数量的列表。仅最后一个参数不会更改,也不必是列表。

这意味着什么:

(nconc '("a" "b" "c") '("d" "e" "f"))
=> ("a" "b" "c" "d" "e" "f")

(setq l1 '("a" "b" "c")
      l2 '("d" "e" "f"))
(nconc l1 l2)
=> ("a" "b" "c" "d" "e" "f")
l1
=> ("a" "b" "c" "d" "e" "f")
l2
=> ("d" "e" "f")

谢谢,但是如果第二个和第三个参数是变量而不是显式列表,则它似乎返回错误。
丹尼尔(Daniele)

1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)可以。
JeanPierre

@Daniele我怀疑您正在尝试引用变量,这意味着它们没有被评估为其列表值。(即您想要varname而不是'varname)。
菲尔斯(Philips)

为了完整起见,我不妨提及在Emacs> = 25 :(seq-concatenate在之后(require 'seq))中连接任何类型的序列的非CL方法,尽管这反过来也只是包装了cl-concatenate
巴兹尔(Basil)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.