Mathematica中使用Clear[symbol_1,symbol_2,... ] 清除符号symbol_i的值和定义。但是,有时需要清除一系列符号的值和定义。比如,
有一系列变量a, b, c构成一个集和,称作 Vars,
Vars={a,b,c,...};
中间计算得到,
a=1; b=2; c=3;...
现在想清除这一系列变量a, b, c,...的值。
虽然可以将每一个要清除的变量列出,用Clear[a,b,c,...]清除,但是如果这个变量的集合很大,元素有成百上万个,那么使用Clear[ ]很不现实。
下面的函数可以实现这一目标,它输入一个列表(List),调用这一函数之后,将清除这个列表里每个变量的值。
基本想法是,先保持输入不变,将输入转变成一个字符串,再从这个字符串中恢复每一个变量相应的子字符串,比如''a"是变量a相应的字符串,最后使用Clear的另外一种用法Clear["symbol_1","symbol_2",... ]清除每个子字符串对应的变量。
(*给函数设定HoldAll属性,防止参数被计算*)
SetAttributes[ClearList, HoldAll];
(*如果输入不是列表List,返回错误信息*)
ClearList::nnarg = "The argument `1` is not a list.";
ClearList[syml_] /;
If[Head[Evaluate[syml]] === List, True,
Message[ClearList::nnarg, syml]; False] := Module[{str, seq},
str[1] = ToString[HoldForm[syml]];
(*ClearList[{}] or ClearList[Var]*)
If[StringFreeQ[str[1], "{" ~~ __ ~~ "}"],
str[1] = ToString[Trace[syml][[2]]]];
(*ClearList[{c0[1],...}]*)
str[2] =
StringReplace[
str[1], {"{" -> "", "}" -> "", "[" ~~ __ ~~ "]" -> ""}];
str[3] = StringSplit[str[2], {", "}];
seq = str[3] /. List -> Sequence;
Clear[Evaluate[seq]];
];
测试如下:
1. Var = {a, c0[1], epsilon};
a = 1; c0[1] = 2; epsilon = 3;
ClearList[Var];
2. a = 1; c0[1] = 2; epsilon = 3;
Var := {a, c0[1], epsilon}; (*此处延迟赋值*)
ClearList[Var];
3. a = 1; c0[1] = 2; epsilon = 3;
ClearList[{a, c0[1], epsilon}] ;