Ale*_*kov 6 wolfram-mathematica
在以前的线程的有效方式删除空列表({}从列表)建议:
Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}]
Run Code Online (Sandbox Code Playgroud)
使用Trott-Strzebonski就地评估技术,这种方法可以推广用于同时使用保持的表达式:
f1[expr_] :=
Replace[expr,
x_List :> With[{eval = DeleteCases[x, {}]}, eval /; True], {0, Infinity}]
Run Code Online (Sandbox Code Playgroud)
此解决方案比基于以下方案的解决方案更有效ReplaceRepeated:
f2[expr_] := expr //. {left___, {}, right___} :> {left, right}
Run Code Online (Sandbox Code Playgroud)
但它有一个缺点:如果它们被包装,它会对持有的表达式进行求值List:
In[20]:= f1[Hold[{{}, 1 + 1}]]
Out[20]= Hold[{2}]
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:在{}不评估保持表达式的情况下从列表中删除所有空列表()的最有效方法是什么?只有当它是另一个自身的元素时,才List[]应删除空对象.List
以下是一些时间安排:
In[76]:= expr = Tuples[Tuples[{{}, {}}, 3], 4];
First@Timing[#[expr]] & /@ {f1, f2, f3}
pl = Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}];
First@Timing[#[pl]] & /@ {f1, f2, f3}
Out[77]= {0.581, 0.901, 5.027}
Out[78]= {0.12, 0.21, 0.18}
Run Code Online (Sandbox Code Playgroud)
定义:
Clear[f1, f2, f3];
f3[expr_] :=
FixedPoint[
Function[e, Replace[e, {a___, {}, b___} :> {a, b}, {0, Infinity}]], expr];
f1[expr_] :=
Replace[expr,
x_List :> With[{eval = DeleteCases[x, {}]}, eval /; True], {0, Infinity}];
f2[expr_] := expr //. {left___, {}, right___} :> {left, right};
Run Code Online (Sandbox Code Playgroud)
怎么样:
Clear[f3];
f3[expr_] :=
FixedPoint[
Function[e,
Replace[e, {a___, {}, b___} :> {a, b}, {0, Infinity}]],
expr]
Run Code Online (Sandbox Code Playgroud)
它似乎符合规格:
In[275]:= f3[{a, {}, {b, {}}, c[d, {}]}]
Out[275]= {a, {b}, c[d, {}]}
In[276]:= f3[Hold[{{}, 1 + 1, {}}]]
Out[276]= Hold[{1 + 1}]
Run Code Online (Sandbox Code Playgroud)