Используйте mapcan
и make-list
(что является библиотечной версией вашего copy
):
(mapcan (lambda (letter num)
(make-list num :initial-element letter))
'(A B C D) '(1 5 4 2))
==> (A B B B B B C C C C D D)
или просто
(mapcan #'copy '(A B C D) '(1 5 4 2))
Если вам необходимо использовать простую рекурсию, вы также можете написать
(defun copy-list-elements (elements counts)
(and elements counts
(let ((count (pop counts)))
(if (plusp count)
(cons (car elements)
(copy-list-elements elements
(cons (1- count) counts)))
(copy-list-elements (cdr elements)
counts)))))
(copy-list-elements '(A B C D E) '(1 5 4 0 2))
==> (A B B B B B C C C C E E)
Обратите внимание, что рекурсивная версия длиннее и, вероятно, медленнее.