Generating HTML for prerolled d20 RPG initiative tables
I wouldn't use strings at all. I would write to a stream.

If wished, I would convert the stream to a string.

(defun d20 () (+ 1 (random 19)))


initlist can be written more compact:

(defun initlist (specs)
  (sort (loop for (a b) in specs collect (list a (+ b (d20))))
        #'&gt; :key #'second))


Now we pass a stream to htmlinitlist and write the contents to the stream:

(defun htmlinitlist (specs stream)
  (write-string "&lt;table&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;" stream)
  (loop for (a b) in (initlist specs) do 
        (format stream
                "&lt;tr&gt;&lt;td&gt;~A&lt;/td&gt;&lt;td&gt;~A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;"
                a b))
  (write-string "&lt;/table&gt;" stream))


If we want to get a string from a stream, we can use with-output-to-string. This binds a stream variable, which we can use and pass around...

(defun htmlinitlists (specs count)
  (with-output-to-string (stream)
    (write-char #\space stream)
    (loop repeat (1+ count) do (htmlinitlist specs stream))))


Alternate version of htmlinitlist using only one FORMAT call:

(defun htmlinitlist (specs stream)
  (format stream
          "&lt;table&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;~
           ~{&lt;tr&gt;&lt;td&gt;~A&lt;/td&gt;&lt;td&gt;~A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;~}~
           &lt;/table&gt;"
          (loop for (a b) in (initlist specs) collect a collect b)))


Benefit

All the various string operations (which are creating lots of intermediate strings which are immediately garbage) have been replaced with the usual output functions and a stream.