¿Cómo concatenar dos listas?

15

Lo siento, pero elisp no es mi mejor. Necesito combinar dos listas de cadenas de esta manera:

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

Bueno, el orden no es importante, así que escribí este código:

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

Funciona, pero me pregunto si hay una función que ya lo haga.

¿Cualquier pista? Gracias por adelantado.

Daniele
fuente
44
Consulte las listas de creación de nodos del manual de Elisp.
Dibujó
2
appendes la respuesta correcta aquí, pero sería otra forma (destructiva) de hacerlo (setcdr (last a) b).
Sean Allred
1
¿Trabajando en listas? dash.el ! (-concat '(1) '(2 3) '(4)) ;; => '(1 2 3 4)
Ehvince
Nunca lo use add-to-listen el código Lisp (dice esto en la cadena de documentación). En cambio, use push.
Radon Rosborough

Respuestas:

25

También puedes usar append.

(append '("a" "b" "c") '("d" "e" "f"))
John Kitchin
fuente
2
Y,(nconc '("a" "b" "c") '("d" "e" "f"))
ley
1
Oh, sí, de hecho appendparece mejor aquí.
JeanPierre
nconc funciona pero, si almacena listas en variables, nconc las modificará. Por ejemplo, (let ((a '(1 2 3)) (b' (3 4 5))) (nconc ab) a) modificará la variable a.
John Kitchin,
1
FYI cl-concatenateusa appendcuando TYPE es list, entonces ambas respuestas están produciendo el mismo resultado.
Phil
Sí, seguramente hace el trabajo. Muchas gracias a todos por su ayuda.
Daniele
3

concatenate es un alias para 'cl-concatenate' en 'cl.el'.

(concatenar SECUENCIA DE TIPO ...)

Concatenar, en una secuencia de tipo TIPO, el argumento SECUENCIAS.

Entonces para tu ejemplo

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

Como está definido en, cles posible que (require 'cl)primero tenga que hacerlo , de lo contrario, puede usar el cl-concatenateque parece estar cargado de forma predeterminada.

Además, como señaló @phils cl-concatenatesolo llama appendcuando TYPE es 'list, aquí está la fuente de cl-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))))

Entonces, si solo usa listas, es más fácil de usar directamente append, como lo señaló @John Kitchin.

Finalmente, @lawlist mencionó nconc:

nconc es una función incorporada en 'código fuente C'.

(nconc & LISTAS de descanso)

Concatene cualquier número de listas al alterarlas. Solo el último argumento no se modifica y no necesita ser una lista.

Lo que esto significa:

(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")
Jean Pierre
fuente
Gracias, pero parece que devuelve un error si el segundo y el tercer argumento son variables y no listas explícitas.
Daniele
1
(setq l1 '("a" "b" "c") l2 '("d" "e" "f")) (concatenate 'list l1 l2)funciona bien
JeanPierre
@Daniele Sospecho que intentabas citar las variables, lo que significa que no se evalúan según sus valores de lista. (es decir, quieres varnamemás que 'varname).
Phil
Para completar, también podría mencionar la forma no CL de concatenar cualquier tipo de secuencia en Emacs> = 25: seq-concatenate(después (require 'seq)), aunque esto a su vez simplemente se cierra cl-concatenate.
Albahaca