Элегантно изменить список переменных: обобщение AddTo, TimesBy и т. Д. - PullRequest
3 голосов
/ 17 января 2011

Предположим, я определил список переменных

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

Если я хочу удвоить их все, я могу сделать это:

{a,b,c} *= 2

Переменные {a, b, c} теперь оцениваются как {2,4,6}. Если я хочу применить к ним произвольную функцию преобразования, я могу сделать это:

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

Как бы вы это сделали, не указав список переменных дважды?

(Отложите возражение, что я, вероятно, хотел бы массив, а не список переменных с четко именованными именами.)

Ответы [ 2 ]

2 голосов
/ 17 января 2011

Вы можете сделать это:

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

Например,

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]}

Или вы можете сделать то же самое без жесткого кодирования f, но с определением пользовательской функции set. Эффект вашего цикла foreach можно легко воспроизвести, если вы зададите ему атрибут Listable:

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

Пример:

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

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

Вы также можете получить преимущества в скорости для случаев, когда ваш f является Listable, что особенно актуально сейчас, поскольку M8 Compile позволяет пользовательским функциям получать выгоду от того, чтобы быть Listabe с точки зрения скорости, способом, который раньше встроенные функции могли. Все, что вам нужно сделать для set для таких случаев (когда вы набираете скорость и знаете, что f является Listable), это удалить атрибут Listable set.

0 голосов
/ 17 января 2011

Я нашел ответ на этот вопрос, когда решил этот старый вопрос: Цикл ForEach в Mathematica

Определив функцию each, как в принятом ответе на этот вопрос, мы можемответьте на этот вопрос:

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