开发者

Elegantly alter a list of variables: Generalization of AddTo, TimesBy, etc

开发者 https://www.devze.com 2023-02-04 20:34 出处:网络
Suppose I\'ve defined a list of variables {a,b,c} = {1,2,3} If I want to double them all I can do t开发者_Python百科his:

Suppose I've defined a list of variables

{a,b,c} = {1,2,3}

If I want to double them all I can do t开发者_Python百科his:

{a,b,c} *= 2

The variables {a,b,c} now evaluate to {2,4,6}. If I want to apply an arbitrary transformation function to them, I can do this:

{a,b,c} = f /@ {a,b,c}

How would you do that without specifying the list of variables twice?

(Set aside the objection that I'd probably want an array rather than a list of distinctly named variables.)


You can do this:

Function[Null, # = f /@ #, HoldAll][{a, b, c}]

For example,

In[1]:= 
{a,b,c}={1,2,3};
Function[Null, #=f/@#,HoldAll][{a,b,c}];
{a,b,c}

Out[3]= {f[1],f[2],f[3]}

Or, you can do the same without hard-coding f, but defining a custom set function. The effect of your foreach loop can be reproduced easily if you give it Listable attribute:

ClearAll[set];
SetAttributes[set, {HoldFirst, Listable}]
set[var_, f_] := var = f[var];

Example:

In[10]:= {a,b,c}={1,2,3};
set[{a,b,c},f1];
{a,b,c}

Out[12]= {f1[1],f1[2],f1[3]}

You may also want to get speed benefits for cases when your f is Listable, which is especially relevant now since M8 Compile enables user-defined functions to benefit from being Listabe in terms of speed, in a way that previously only built-in functions could. All you have to do for set for such cases (when you are after speed and you know that f is Listable) is to remove the Listable attribute of set.


I hit upon an answer to this when fixing up this old question: ForEach loop in Mathematica

Defining the each function as in the accepted answer to that question, we can answer this question with:

each[i_, {a,b,c}, i = f[i]]
0

精彩评论

暂无评论...
验证码 换一张
取 消