This is not 100% identical, but in most cases will be equivalent:
(defmacro set-term-faces (names)
`(custom-set-faces
,@(loop for color in names
for sym = (intern (concat "term-color-" (symbol-name color)))
collect (list 'quote
`(,sym ((t (:inherit ,sym
:background
,(face-attribute sym :foreground)))))))))
(set-term-faces (black red green yellow blue magenta cyan white))
The discrepancy is at the point of when the evaluation of ,(face-attribute ...)
happens. I.e. this macro doesn't produce the same source code you have, it already evaluates the expression after comma, so if your code was inside a macro, that would make a difference.