SymbolName应用于变量列表,其中一些变量可能已分配值

时间:2015-06-25 03:59:52

标签: wolfram-mathematica

在Mathematica中:

我想将一个可变数量的参数传递给函数。

我想打印每个参数的名称。问题是SymbolName评估其输入。对于给定的变量,您可以解决这个问题:

a=18;
SymbolName[Unevaluated[a]]

的工作原理。但是如果变量在列表中,那将无效。例如:

printname[x__]:=Print[Table[SymbolName[Unevaluated[{x}[[i]]]],{i,1,Length[{x}]}]];
printname[a,b,c]

不起作用。有什么建议吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

Mathematica在您调用时会尝试评估Unevaluated[]的参数。因此{x}[[i]]转换为您不想要的{18, b, c}[[i]],然后i上的迭代不再起作用,因为Unevaluated[]不允许Table访问迭代器。

因此,要真正解决问题,您应该完全禁用Mathematica对您希望传递符号的函数的评估。

In[1]:= SetAttributes[SymbolName, HoldAll];
        SetAttributes[Map, HoldAll];

在此之后你可以做到

In[2]:= a=18; SymbolName @@@ Unevaluated /@ {a, b, c}
Out[2]:= {a, b, c}

其中@@@/@Apply[]Map[]的简写。

在Mathematica的内置函数中设置Hold[]或类似属性可能会导致麻烦。有关详细信息,请参阅Mathematica stackexchange中的this问题和答案。

具体来说,使一个带有任意数量参数的函数是

sym = SymbolName @@@ Unevaluated /@ {##} &

但为List[]函数接受参数序列##的{​​{1}}函数将再次评估&并将a打开为{{1}不行。

因此,最简单的方法是使用HoldAll定义一个函数,该函数只将args作为局部变量列表传递给List[]。这使得创建一个孤立的上下文,其中变量不会评估为任何内容。

HoldAll