Emacs Lisp: List

Buy Xah Emacs Tutorial. Master emacs benefits for life.
, , …,

This page is a basic tutorial of Emacs Lisp's list datatype.

Create List

To create a list, write it like this (list a b …).

; assign a list to a var
(setq myList (list 1 "b" 3))
; prints a list
(message "%S" myList)

If you do not want the elements evaluated, write it like this: '(a b …). This is equivalent to (quote (list a b …))

; assign a list to a var
(setq myList '(a b c))

; prints a list
(message "%S" myList)
;; create a list of values of variables
(let ((x 3) (y 4) (z 5))
  (message "%S" (list x y z))
  ) ; prints "(3 4 5)"

Create Number Sequence (Range)

(number-sequence n m step) → returns a list of a range of numbers, from n to m, in increment of m.

;; creating a range of numbers
(number-sequence 5) ; (5)

(number-sequence 2 9) ; (2 3 4 5 6 7 8 9)

(number-sequence 0 9 3) ; (0 3 6 9)

Length

(length list) → return number of elements.

(length (list "a" "b" "c") ) ; 3

Get Elements of a List

List index count starts from 0.

list element extraction functions
FunctionPurpose
(car list)first element
(nth n list)nth element
(car (last list))last element
(car (list "a" "b" "c") )   ; "a"
(nth 1 (list "a" "b" "c") ) ; "b"
(car (last (list "a" "b" "c")) )   ; "c"
sublist functions
FunctionPurpose
(cdr list)2nd to last elements.
(nthcdr n list)nth to last elements.
(butlast list n)without the last n elements.
(cdr (list "a" "b" "c") )   ; ("b" "c")
(butlast (list "a" "b" "c" "d") )   ; ("a" "b" "c")
(butlast (list "a" "b" "c" "d") 2)   ; ("a" "b")

Prepend, Append

Basic List Functions
FunctionPurpose
(cons x list)Return a new list, with x added to front. (prepend)
(append list1 list2)Return a new list, of the two lists
(cons "a" (list "c" "d") ) ; ("a" "c" "d")

(cons (list "a" "b") (list "c" "d") ) ; (("a" "b") "c" "d")
(append (list "a" "b") (list "c" "d") ) ; ("a" "b" "c" "d")

Modify List Variable

Functions that modify a list variable
FunctionPurpose
(push list)Add a element to the front variable. Returns the new list.
(pop list)Remove first element from the variable. Returns the removed element.
(nbutlast list n)Remove last n elements from the variable. Returns the new value of the variable.
(setcar list x)replaces the first element in list with x. Returns x.
(setcdr list x)replaces the rest of elements in list with x. Returns x.
(let ((x '(1)))
  (push 2 x)
  (equal x '(2 1)) ; true
  )
(setq mylist '("a" "b" "c"))
(pop mylist)   ; "a"
(print mylist) ; ("b" "c")

The weird names {car, cdr, cons} are like that for historical reasons.

(info "(elisp) Lists")

Map: mapcar, mapc

Here's a typical way of going thru a list. It is done with mapcar.

(mapcar function sequence) → Apply function to each element of sequence, and make a list of the results. sequence may be a list, a vector, a bool-vector, or a string.

; add one to each list member
(mapcar '1+ (list 1 2 3 4)) ; (2 3 4 5)
; take the 1st element of each
(mapcar 'car '((1 2) (3 4) (5 6))) ; (1 3 5)

Examples use user-defined function “lambda” created inline:

; add one to each list member
(mapcar
 (lambda (x) (+ x 1))
 (list 1 2 3 4)
) ; (2 3 4 5)
;; take the 2nd element of each
(mapcar (lambda (x) (nth 1 x))
        '((1 2) (3 4) (5 6))) ; (2 4 6)

The lambda above means function. It let you define a function in the middle of your code. The form is (lambda (args) body). For example, (lambda (x y) (+ x y)) is a function that takes two arguments, x and y, and returns their sum.

Loop thru List

mapc

mapc → like mapcar, but returns nil.

;; apply a file processing function to a list of files
(mapc 'my-update-html-footer
      (list
       "~/web/file1.html"
       "~/web/file2.html"
       "~/web/file3.html"
       ))

dotimes

dotimes is useful when you want to go thru a list with a index.

dotimes (var n) body → run body, with var set to 0 to n-1.

dotimes (var n result) body → returns result.

(setq mylist (make-list 8 0) ) ; creates '(0 0 0 0 0 0 0 0)

(dotimes (i (length mylist))
  (insert (number-to-string i))) ; inserts "01234567", returns nil

using while

Another common form to loop thru a list is using the while function. In each iteration, pop is used to reduce the list.

(let ((myList '(a b c)))
  (while myList
    (message "%s" (pop myList))
    (sleep-for 1)))

List vs Vector

     _____________________________________________
    |                                             |
    |          Sequence                           |
    |  ______   ________________________________  |
    | |      | |                                | |
    | | List | |             Array              | |
    | |      | |    ________       ________     | |
    | |______| |   |        |     |        |    | |
    |          |   | Vector |     | String |    | |
    |          |   |________|     |________|    | |
    |          |  ____________   _____________  | |
    |          | |            | |             | | |
    |          | | Char-table | | Bool-vector | | |
    |          | |____________| |_____________| | |
    |          |________________________________| |
    |_____________________________________________|

Lisp's listvector both are subtypes of the “sequences” datatype. Many functions, such as {elt, mapcar}, work on any sequence type. Here's their primary differences:

〔➤ Emacs Lisp: Vector

Lisp culture is to almost always use list. I recommend using vector as much as possible. Use list ONLY IF you need to constantly grow the list. Even for that case, i recommend using vector by starting with large length, using the function make-vector. 〔➤ Guy Steele on Parallel Programing: Get rid of cons!

You can nest list & vectors in any way. Example:

;; mixed nested list/vector

[ '(3 4) '(5 8) [4 2]]

(list [8 7] '(4 1))

(info "(elisp) Sequences Arrays Vectors")

List of Pairs: Association List & Hash Table

Association List (alist)

Another important datatype similar to list & vector is called Association List (aka alist). It is similar to Python Dictionary, Ruby Hash Table. See: (info "(elisp) Association Lists").

For a example of using alist, see: Emacs Lisp: Batch Script to Validate Matching Brackets.

Like it? Buy Xah Emacs Tutorial.
blog comments powered by Disqus