Wolfram mathematica 从列表中删除空列表的有效方法?

Wolfram mathematica 从列表中删除空列表的有效方法?,wolfram-mathematica,Wolfram Mathematica,从表达式中不同级别出现的所有列表中删除所有空列表[]对象的最有效方法是什么?只有当空的列表[]是另一个列表本身的元素时,才应删除它。安德鲁和亚历克赛指出,使用expr//。x_List:>DeleteCases[x,{},无穷远]正如我在上一个答案中所做的那样,它也会删除blah[{f[{}]}]中的{},而它应该保持它的头部是f,而不是列表。多亏了Leonid,解决方案是不使用ReplaceRepeated,而是Replace,在0到Infinity的所有级别进行替换: Replace[exp

从表达式中不同级别出现的所有
列表中删除所有空
列表[]
对象的最有效方法是什么?只有当空的
列表[]
是另一个
列表
本身的元素时,才应删除它。

安德鲁和亚历克赛指出,使用
expr//。x_List:>DeleteCases[x,{},无穷远]
正如我在上一个答案中所做的那样,它也会删除
blah[{f[{}]}]
中的
{}
,而它应该保持它的头部是
f
,而不是
列表。多亏了Leonid,解决方案是不使用
ReplaceRepeated
,而是
Replace
,在
0
Infinity
的所有级别进行替换:

Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}]

从这个小例子可以看出
Replace
有效而
ReplaceRepeated
无效的原因。考虑<代码> ExpR= {a,{},{b,{}},c[d,{}] };<代码>在其
TreeForm

Replace
首先从最里面的表达式开始工作,即
List[b,{}]
c[d,{}]
,然后向上工作到顶部节点。在每个级别上,检查头部都非常简单,只需抬头查看正上方的节点,看看它是否匹配
列表
。如果是,则应用规则并向上移动一个级别,否则不执行任何操作并向上移动一个级别。这将生成最终的树:

另一方面,
ReplaceRepeated
/)
)则从最顶端的节点开始向下遍历树。前面的解决方案首先检查第一个节点是否是
列表
,如果是,则应用
DeleteCases
,并向下移动树,无情地替换它能找到的每个
{}
。请注意,它不会检查内部表达式的头是否也匹配
列表
,因为此遍历是通过
删除案例
,而不是
替换重复
完成的。当
/.
移动到后续较低的节点时,就没有什么可替换的了,它会很快退出。这是使用上一个解决方案得到的树:

请注意,
c[d,{}]
中的
{}
也已删除。这完全是因为
DeleteCases
(具有级别规范
{0,无穷大}
的情况下)会向下移动。事实上,如果第一个头不是
列表
,它会跳过它并移动到下一个级别,其中只有
{b,{}中的
{code>
是一个匹配项。要演示
expr2=f[a,{},{b,{},c[d,{}]]
,我们得到

请注意,在当前使用
Replace
的解决方案中,我们将
DeleteCases
与默认级别规范一起使用,默认级别规范仅为第一级。因此,它不会检查和删除比第一级更深的空列表,这正是我们在此需要的


虽然我们使用了第一个节点来解释它失败的原因,但推理对每个节点都是正确的。Leonid在

中更详细地解释了这些概念。这也将删除除列表以外的头部中的空列表,从而与规范相矛盾。你的新解决方案很棒,非常有效。比我的任何一个都快得多。+1.不起作用在
blah[a,b,{{{{}},d,{e,f,{},g}]/.x{u列表:>DeleteCases[x,{}]
=>
blah[a,b,{{{{}},d,{e,f,g}]
.Add
Infinity
DeleteCases
DeleteCases
[expr,x_List:>DeleteCases[x,{}],{0,无穷大}]
。由于
Replace
从下到上(深度优先)进行操作,与
ReplaceRepeated
不同,问题自然得到解决。它比
DeleteCases[expr,{}]慢得多
版本。作为一个副产品,您不需要重复的规则应用程序。我在这里讨论了
Replace
ReplaceRepeated
之间的区别:。这似乎是一个很好的问题来说明它。@Alexey您测试了您的建议吗?它似乎不起作用。请尝试任何测试用例,比如
{{}
等等[a,b,{{{},d,{e,f,{},g}]
问题是,如果没有进行评估(这是这些测试用例的情况),由
Replace
还原
Unevaluated
wrappers引起的子求值。因此,对于惰性表达式,
Unevaluated
不会给您带来任何好处,只会破坏一些东西。如果要对可能求值的代码执行列表删除操作,这是另一个问题。