Emacs Lisp: List

By Xah Lee. Date: . Last updated: .

Emacs Lisp's list datatype is an ordered sequence of things. It is known as linked list data structure in computer science. It is an efficient datatype for stack data structure. (like a stack of books, allowing adding or removing one item at a time from the top in an efficient way.)

Lisp list are made up of lower structure called cons, as nested Cons Pair.

Any item can be of any type.

Algorithm properties of lisp list:

Create List (Literal Expression)

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

(list args)
create a list of items.
; assign a list to a var
(setq xx (list 1 "b" 3))
; prints a list
(message "%S" xx)

If you do not want the elements evaluated, write it like this:

'(a b etc)

This is equivalent to

(quote (a b etc))

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

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

Empty List, nil

In elisp, empty list is equivalent to nil. The following are all equivalent.

(eq '() (list ) ) ; t
(eq '() nil); t
(eq (list ) nil ) ; t

[see Emacs Lisp: Test Equality]

Create List of Same Value

(make-list LENGTH INIT)
Create a list of length LENGTH, and all elements with value INIT.
(equal (make-list 3 0) '(0 0 0))

Create List of Range of Numbers

(number-sequence n)
Return a list of 1 element of value n.
;; just 1 element
(equal
 (number-sequence 5)
 '(5))
(number-sequence n m)
return a list from n to m.
;; n to m, inclusive
(equal
 (number-sequence 2 5)
 '(2 3 4 5))
(number-sequence n m step)
Return a list of a range of numbers, from n to m, in increment of step.
;; using 3 as step
(equal
 (number-sequence 0 9 3)
 '(0 3 6 9))

(equal
 (number-sequence 0 9 2)
 '(0 2 4 6 8))
;; ending item dropped

;; negative step
(equal
 (number-sequence 4 0 -1)
 '(4 3 2 1 0))

;; boundaries can be float but will not include
(equal
 (number-sequence 2.2 5.3)
 '(2.2 3.2 4.2 5.2))

Length

(length SEQUENCE)
return count of elements.
(equal (length '("a" "b" "c") ) 3)

Get Element from List

(car list)
first element
(equal
 (car '("a" "b" "c"))
 "a"
 )
(cdr list)
rest elements
(equal
 (cdr '(0 1 2 3 4))
 '(1 2 3 4))
(nth n list)
nth element. (Index starts from 0.)
(equal
 (nth 1 '(0 1 2 3 4))
 1)
(nthcdr n list)
rest starting at n.
(equal
 (nthcdr 2 '(0 1 2 3 4))
 '(2 3 4))
(last list)
last as a list. i.e. return (cons lastElement nil).

To get the actual last item of a list, do (car (last list))

(equal
 (car (last (list "a" "b" "c")))
 "c"
 )

(equal
 (last (list "a" "b" "c"))
 (cons "c" nil)
 )
(last list &optional n)
last n items.
(equal
 (last '(0 1 2 3 4 5 6) 2)
 '(5 6)
 )
(butlast list n)
without the last n elements.
(equal
 (butlast '(0 1 2 3 4 5))
 '(0 1 2 3 4))

(equal
 (butlast '(0 1 2 3 4 5) 2)
 '(0 1 2 3))

Add to List

(cons new list)
Return a new list, with new added to front. (prepend)
(equal
 (cons "a" '("c" "d"))
 '("a" "c" "d"))

(equal
 (cons '("a" "b") '("c" "d"))
 '(("a" "b") "c" "d"))
(add-to-list LIST-VAR ELEMENT &optional APPEND COMPARE-FN)
Add to list when not already in it.
(setq xx '(1 2 3))

;; add "a" to it. return the modified var
(eq
 (add-to-list 'xx "a" )
 xx)

;; check the new value
(equal
 xx
 '("a" 1 2 3))
(add-to-ordered-list LIST-VAR ELEMENT &optional ORDER)
Add to specific position in list, if it does not exist. The list is reordered.

Modify List Variable

The following are designed to modify a list variable in-place.

(push new listVar)
  • Add element to the front.
  • Modify the listVar.
  • Return the new value of listVar
(setq xx '(1))

;; after push, the var is modified, and the var's new value is returned
(eq (push 2 xx) xx)

(equal xx '(2 1))

The variable is modified even if the pushed list is inside a list.

;; a list of lists
(setq xx '((1 2) (3 4) (5 6)))

;; push b to one of the list
(equal
 (push "b" (nth 1 xx))
 '("b" 3 4))

;; the xx is modified
(equal
 xx
 '((1 2) ("b" 3 4) (5 6)))

also if the variable is a vector:

;; a vector of lists
(setq xx [(1 2) (3 4) (5 6)])

;; push b to one of the list
(equal
 (push "b" (aref xx 1))
 '("b" 3 4 ))

;; the xx is modified
(equal
 xx
 [(1 2) ("b" 3 4 ) (5 6)]
 )
(pop listVar)
Remove first element from the variable. Return the removed element.
(setq xx '(1 2 3 4))
(equal (pop xx) 1)
(equal xx '(2 3 4))
(nbutlast listVar n)
Remove last n elements from the variable. Return the new value of the variable.
(setq xx '(0 1 2 3))
(equal (nbutlast xx 1) '(0 1 2))
(equal xx '(0 1 2))
(setcar listVar new)
Replace the first element in listVar with new. Return new.
(setq xx '(1 2 3 4))
(equal (setcar xx "a") "a")
(equal xx '("a" 2 3 4))
(setcdr listVar newTail)
Replace the rest of elements in listVar with newTail. Return newTail.

Warning: if you want the result to be a Proper List, the newTail should be a proper list.

(setq xx '(1 2 3 4))

(equal
 (setcdr xx (cons "a" nil))
 (cons "a" nil))

(equal xx '(1 "a"))

Append, Join Lists

List to String

Reference

(info "(elisp) Lists")

Lisp Basics

Lisp Data Structure


Lisp Basics

Basics

Lisp Data Structure

Function

Lisp Symbol

Lisp Misc

Working with Elisp