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

时间:2011-07-03 12:36:17

标签: wolfram-mathematica

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

1 个答案:

答案 0 :(得分:21)

安德鲁和阿列克谢指出,使用expr //. x_List :> DeleteCases[x, {}, Infinity],就像我之前的回答一样,也会删除{}中的blah[{f[{}]}],而它应该保持不变,因为它的头部是{{} 1}},而不是f。感谢Leonid,解决方案是不使用List,而是使用ReplaceRepeated代替从Replace0的所有级别进行替换:

Infinity

从这个小例子中可以看出Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}] 工作原因和Replace的原因。在ReplaceRepeated

中考虑expr = {a, {}, {b, {}}, c[d, {}]};

enter image description here

TreeForm首先从最里面的表达式开始工作,即ReplaceList[b,{}],然后向上工作到顶部节点。在每个级别,检查头部就像查看上面的节点一样简单,看它是否与c[d,{}]匹配。如果是,则应用规则并向上移动一个级别,否则不执行任何操作并向上移动一个级别。这导致最终树:

enter image description here

ListReplaceRepeated,另一方面,从最顶层的节点开始并遍历树。先前的解决方案首先检查第一个节点是否为{{1}如果是,则应用//.)并向下移动树,无情地替换它可以找到的每个List。请注意,它不会检查内部表达式的头部是否也匹配{{ 1}},因为此遍历由DeleteCases完成,而不是{}。当List移动到后续的较低节点时,没有什么可以替换它并且它会快速退出。这就是树那个人得到了以前的解决方案:

enter image description here

请注意,DeleteCases内的ReplaceRepeated也已被删除。这完全是因为//.(级别规范{}向下移动树。事实上,如果第一个头部不是c[d, {}],它就会跳过它并移至下一级,其中只有DeleteCases中的{0,Infinity}才匹配。要使用List进行演示,我们会​​得到

enter image description here

请注意,在使用{}的当前解决方案中,我们使用{b, {}}和默认级别规范,这是第一级。因此,它不会检查和删除比第一级更深的空列表,这正是我们在这里所需要的。

虽然我们使用第一个节点来解释它失败的原因,但推理适用于每个节点。 Leonid在his book

中更详细地解释了这些概念