The following defines a fully expandable variant of your \average macro. I also added an optional argument to provide the rounding precision.
You don't need anything else to also access variables, be they defined as macros or fp variables.
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \xcn_mean:n #1
{ \fp_eval:n { ( \clist_use:nn {#1} { + } ) / \clist_count:n {#1} } }
\NewExpandableDocumentCommand \average { o m }
{
\IfNoValueTF {#1}
{ \xcn_mean:n {#2} }
{ \fp_eval:n { round ( \xcn_mean:n {#2}, #1 ) } }
}
\fp_new_variable:n { aaa }
\fp_set_variable:nn { aaa } { 3.7 }
\ExplSyntaxOff
\begin{document}
\average[3]{1,aaa,5} % would return 3.233
\average{1,3.7,5,3.2*2,7.9} % would return 4.8. the argument number is arbitrary but limited
\end{document}
An extended variant that also allows to calculate the mean of the return values of a function. I use expkv-cs to split the optional argument as a key=value argument with the two keys round and f. The notation V:~ in the key definition list is the same as \exp_args:NV for keys in expkv and the other related packages (note that the ~ is only to be used in \ExplSyntaxOn, outside of that scope it should be V: ).
\documentclass{article}
\usepackage{expkv-cs}
\ExplSyntaxOn
\cs_new:Npn \xcn_mean:n #1
{ \fp_eval:n { ( \clist_use:nn {#1} { + } ) / \clist_count:n {#1} } }
\cs_new:Npn \xcn_mean_function:nn #1#2
{
\fp_eval:n
{
( \clist_map_tokens:nn {#2} { \__xcn_mean_function_aux:nn {#1} } )
/ \clist_count:n {#2}
}
}
\cs_new:Npn \__xcn_mean_function_aux:nn #1#2 { +(#1(#2)) }
\NewExpandableDocumentCommand \average { O{} m }
{ \__xcn_average:nn {#1} {#2} }
\ekvcSplitAndForward \__xcn_average:nn \__xcn_average_aux:nnn
{
V:~ round = \c_novalue_tl
,V:~ f = \c_novalue_tl
}
\cs_new:Npn \__xcn_average_aux:nnn #1#2#3
{
% #1: round
% #2: f
% #3: clist
\tl_if_novalue:nTF {#1}
{ \__xcn_average_aux:nn {#2} {#3} }
{ \fp_eval:n { round ( \__xcn_average_aux:nn {#2} {#3}, #1 ) } }
}
\cs_new:Npn \__xcn_average_aux:nn #1#2
{
\tl_if_novalue:nTF {#1}
{ \xcn_mean:n {#2} }
{ \xcn_mean_function:nn {#1} {#2} }
}
\fp_new_variable:n { aaa }
\fp_set_variable:nn { aaa } { 3.7 }
\fp_new_function:n { sq }
\fp_set_function:nnn { sq } { x } { x**2 }
\ExplSyntaxOff
\begin{document}
\average[round=3]{1,aaa,5} % would return 3.233
\average{1,3.7,5,3.2*2,7.9} % would return 4.8. the argument number is arbitrary but limited
\average[f=sq]{1, 2, 3, 4} % 30/4 = 7.5
\end{document}