【问题标题】:SymbolName applied to a list of variables, some of which may have values assignedSymbolName 应用于变量列表,其中一些变量可能已赋值
【发布时间】:2015-06-25 03:59:52
【问题描述】:

在数学中:

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

我想打印每个参数的名称。问题是 SymbolName 评估它的输入。对于给定的变量,你可以绕过这个:

a=18;
SymbolName[Unevaluated[a]]

有效。但如果变量在列表中,这将不起作用。例如:

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

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

提前致谢。

【问题讨论】:

  • 请详细说明您的问题并正确格式化您的代码。

标签: wolfram-mathematica


【解决方案1】:

当您调用 Unevaluated[] 时,Mathematica 会尝试计算它的参数。所以{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[] 函数将再次评估a 并为List[] 打开HoldAll 是不行的。

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

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}

【讨论】:

  • Timo,我不知道发生了什么事以及为什么我没有早点跟进,但感谢您迟来的答复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 2015-08-11
  • 1970-01-01
相关资源
最近更新 更多