Iterating through lists is fairly common and allows for compact code when using an appropriate definition. I often find that dealing with head/tail elements in the list requires special care. Here's an example (using etoolbox, although it holds for most processors/parsers):

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
\renewcommand*{\do}[1]{#1##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}
Processing the list in this generic way - placing a delimiter/separator followed by the item - leaves the head with an unwanted delimiter. One way to get rid of this is to define a new delimiter that delays its use for one cycle:

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
\def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
\renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
\docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}
At the first cycle and call to \do, \itemdelim redefines itself so that it effectively sets nothing. At subsequent calls to \do, \itemdelim is fully-defined and just sets the delimiter.
Of course, this could be extended to whatever delay you want (not just a single cycle).
The alternative would be do condition on setting the delimiter based on the number of elements up to a certain point. Although intuitive, this is a little more cunning and uses TeX's macro expansion to its advantage.
\let\num\m@neA few commands later the programmer then did\global\advance\num2This dangerously changes the meaning of\m@ne, as\showthe\m@neshows. The assignment is dangerous enough without\global. – Ahmed Musa Dec 15 '11 at 17:19