(defun pick-new (lst el) (if (eql (car (car lst)) el) (cons (cons el (car lst)) (cdr lst)) (cons (list el) lst))) (defun pack (lst) (reverse (reduce #'pick-new lst :initial-value nil))) #### (defun pick-new (lst el) (cons (cons el (when (equal el (caar lst)) (pop lst))) lst)) (defun pack (lst) (reverse (reduce #'pick-new lst :initial-value nil))) #### ;;With loop: (defun pack(lst &optional groups) (loop for el in lst for first-group = (when (equal el (caar groups)) (pop groups)) do (push (cons el first-group) groups)) (reverse groups)) ;;With recursion: (defun pack(lst &optional groups) (if (not lst) (reverse groups) (let* ((el (pop lst)) (first-group (when (equal el (caar groups)) (pop groups)))) (pack lst (cons (cons el first-group) groups))))) ;;With no mercy: (defun pack(lst &optional g) (if (not lst) (reverse g) (pack (cdr lst) (cons (cons (car lst) (when (equal (car lst) (caar g)) (pop g))) g)))))