Reversing An Emacs Lisp List In-Place

Yesterday, Xah Lee put up a post that showed how to reverse arrays and lists in various languages, including Emacs Lisp. His Elisp examples worked only for arrays so I added one for lists in the comments. Later I realized that although it was pretty efficient it wasn’t really a solution because it built a separate list.

Here’s a less efficient method that does do the reverse in-place

(let ((list '(a b c d e f g)))
  (do ((i 0 (1+ i))
       (j (1- (length list)) (1- j)))
      ((>= i j) list)
    (rotatef (nth i list) (nth j list))))

If you’re not familiar with (or don’t like) the do macro, here’s the same strategy rendered with a while.

(let* ((list '(a b c d e f g)) (l 0) (r (1- (length list))))
  (while (< l r)
    (rotatef (nth l list) (nth r list))
    (incf l)
    (decf r))
  list)

We can also use rotatef to reverse an array

(let ((vec ["a" "b" "c" "d" "e" "f" "g"]))
  (do ((i 0 (1+ i))
       (j (1- (length vec)) (1- j)))
      ((>= i j) vec)
    (rotatef (aref vec i) (aref vec j))))

Of course, all this is a bit silly because Elisp already has this covered. The best and fastest way to reverse a list in-place is

(let ((list '(a b c d e f g)))
  (nreverse list))
This entry was posted in Programming and tagged , . Bookmark the permalink.