A solution with expl3:
\documentclass{article}
\usepackage{xparse,environ,xspace}
\ExplSyntaxOn
\NewEnviron{commalist}[1][\space]{\spence_comma_list:V \BODY #1}
\seq_new:N \l_spence_items_seq
\cs_new_protected:Npn \spence_comma_list:n #1
{
\seq_set_split:Nnn \l_spence_items_seq { \item } { #1 }
\seq_pop_left:NN \l_spence_items_seq \l_tmpa_tl % we have an empty element at the beginning
\seq_use:Nnnn \l_spence_items_seq { ~ and ~ } { , ~ } { , ~ and ~ }
}
\cs_generate_variant:Nn \spence_comma_list:n { V }
\ExplSyntaxOff
\begin{document}
Here is a comma list
\begin{commalist}
\item Item A
\item Item B
\item Item C
\end{commalist}
and another
\begin{commalist}
\item Item A
\item Item B
\end{commalist}
and another
\begin{commalist}
\item Item A
\end{commalist}
which ends the game.
Another one to see that a period can follow
\begin{commalist}[.]
\item Item A
\item Item B
\item Item C
\end{commalist}
\end{document}
A punctuation after the list should be specified beforehand as optional argument, because \NewEnviron works hard to gobble a space following \end{commalist}.
The code prior to the addition of \seq_use:Nnnn follows, just in order to appreciate the elegance of the new method. Thanks to Bruno for providing it.
\ExplSyntaxOn
\NewEnviron{commalist}[1][\space]{\spence_comma_list:V \BODY#1}
\cs_new_protected:Npn \spence_comma_list:n #1
{
\seq_set_split:Nnn \l_spence_items_seq { \item } { #1 }
\seq_pop_left:NN \l_spence_items_seq \l_tmpa_tl % we have an empty element at the beginning
\seq_pop_right:NN \l_spence_items_seq \l_spence_lastitem_tl
\seq_if_empty:NTF \l_spence_items_seq
{
\tl_use:N \l_spence_lastitem_tl
}
{
\spence_andify:
}
}
\cs_new_protected:Npn \spence_andify:
{
\seq_pop_right:NN \l_spence_items_seq \l_spence_lastbutoneitem_tl
\seq_map_inline:Nn \l_spence_items_seq { ##1,~ }
\tl_use:N \l_spence_lastbutoneitem_tl
\c_space_token and ~
\tl_use:N \l_spence_lastitem_tl
}
\cs_generate_variant:Nn \spence_comma_list:n { V }
\tl_new:N \l_spence_lastbutoneitem_tl
\tl_new:N \l_spence_lastitem_tl
\seq_new:N \l_spence_items_seq
\ExplSyntaxOff
\item[\kern-0.3em] Item A. I suppose that there is no easy way to get rid of the space – Jul 09 '12 at 06:16\setlist[commalist]{before=\kern-0.3em, ...}seems to work. – Hans Lundmark Aug 14 '12 at 12:59mode=unboxed. However in this case "itemjoin*is ignored". – Joe Corneli Mar 09 '16 at 13:35