SymbolName 应用于变量列表,其中一些可能已分配值 [英] SymbolName applied to a list of variables, some of which may have values assigned

查看:22
本文介绍了SymbolName 应用于变量列表,其中一些可能已分配值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Mathematica 中:

In Mathematica:

我想将可变数量的参数传递给函数.

I would like to pass a variable number of arguments to a function.

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

I would like to print the name of each argument. The problem is that SymbolName evaluates its input. For a given variable, you can get around this:

a=18;
SymbolName[Unevaluated[a]]

有效.但是如果变量在列表中,那将不起作用.例如:

works. But that won't work if the variable is in a list. For example:

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

不会工作.有什么建议吗?

will not work. Any suggestions?

提前致谢.

推荐答案

Mathematica 会在您调用 Unevaluated[] 的参数时尝试对它求值.所以 {x}[[i]] 被转换成你不想要的 {18, b, c}[[i]] ,然后迭代 {18, b, c}[[i]]code>i 不再工作,因为 Unevaluated[] 不允许 Table 访问迭代器.

Mathematica tries to evaluate the argument of Unevaluated[] when you call it. So {x}[[i]] gets converted into {18, b, c}[[i]] which you didn't want and then the iteration over i doesn't work anymore because Unevaluated[] doesn't let the Table access the iterator.

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

So, to really solve the issue you should disable Mathematica's evaluation completely for the functions that you want to pass the symbols through.

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

之后你就可以了

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

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

where @@@ and /@ are shorthand for Apply[] and Map[].

在 Mathematica 的内置函数中设置 Hold[] 或类似属性可能会导致问题.见 问题和答案在 Mathematica 堆栈交换中以获取更多信息.

Setting Hold[] or similar attributes in Mathematica's built in functions can lead to trouble. See this question and answer in the Mathematica stackexchange for more information.

具体来说,要创建一个接受任意数量参数的函数将是

Specifically, to make a function that takes an arbitrary number of arguments would be

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

但是 List[] 函数接受函数 & 的参数序列 ## 将再次计算 a 并为 List[] 开启 HoldAll 是不行的.

But the List[] function that takes the sequence of arguments ## for the function & will again evaluate a and turning HoldAll on for List[] is not OK.

因此,最简单的方法是定义一个带有 HoldAll 的函数,该函数只是将 args 作为局部变量列表传递到 Block[] 中.这使得 a 创建了一个孤立的上下文,其中变量不计算任何内容.

Thus the easiest way to do this is to define a function with HoldAll that just passes the args into a Block[] as the list of local variables. This makes a creates an isolated context where the variables do not evaluate to anything.

In[1]:= SetAttributes[f, HoldFirst];
In[2]:= f[seq__] := Block[{seq}, Print[SymbolName /@ {seq}]];
In[3]:= a=18; f[a, b, c]
Out[3]:= {a, b, c}

这篇关于SymbolName 应用于变量列表,其中一些可能已分配值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆