【问题标题】:Efficient way to remove empty lists from lists?从列表中删除空列表的有效方法?
【发布时间】:2011-07-03 12:36:16
【问题描述】:

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

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:

    Andrew 和 Alexey 指出,使用 expr //. x_List :> DeleteCases[x, {}, Infinity] 在我之前的回答中也会删除 {} 中的 blah[{f[{}]}],而它应该保持不变,因为它的头部是 f,而不是 @987654331 @。多亏了 Leonid,解决方案是不使用ReplaceRepeated,而是使用Replace,而是在从0Infinity 的所有级别进行替换:

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

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

    Replace 首先从最里面的表达式开始工作,即List[b,{}]c[d,{}],然后向上工作到顶部节点。在每个级别,检查头部就像查看正上方的节点并查看它是否匹配List 一样简单。如果是,则应用规则并向上移动一个级别,否则什么都不做并向上移动一个级别。这会产生最终的树:

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

    请注意,c[d, {}] 中的 {} 也已被删除。这完全是因为DeleteCases(使用级别规范{0,Infinity} 向下移动了树。事实上,如果第一个头不是List,它会跳过它并移动到下一个级别,其中只有{b, {}}中的{}是匹配的。用expr2 = f[a, {}, {b, {}}, c[d, {}]]演示,我们得到

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

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

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

    【讨论】:

    • 这也将删除头部内的空列表而不是列表,因此与规范相矛盾。
    • 您的新解决方案非常棒,非常高效。比我的任何一个都快得多。 +1。
    • blah[a, b, {{{}}}, d, {e, f, {}, g}] //. x_List :> DeleteCases[x, {}] 上无法正常工作==> blah[a, b, {{{}}}, d, {e, f, g}]。将Infinity 添加到DeleteCases
    • @yoda, @Alexey, @Sjoerd 看来治愈@yoda 的解决方案所需要做的就是使用Replace:Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}]。由于Replace 从下到上(深度优先),与ReplaceRepeated 不同,问题自然得到解决。然而,它比DeleteCases[expr,{}] 版本慢得多。作为副产品,您不需要重复的规则应用程序。我在这里讨论了ReplaceReplaceRepeated 之间的区别:mathprogramming-intro.org/book/node218.html。这似乎是一个很好的问题来说明它。
    • @Alexey 你测试你的建议了吗?它似乎不起作用。尝试任何测试用例,比如{{{}}}blah[a, b, {{{}}}, d, {e, f, {}, g}]。问题是,如果没有进行评估(这些测试用例就是这种情况),Replace 引起的子评估会恢复 Unevaluated 包装器。因此,对于惰性表达式,Unevaluated 不会给你买任何东西,只会破坏东西。如果你想对一段可能求值的代码执行列表删除操作,这是一个单独的问题。
    猜你喜欢
    • 2015-07-17
    • 2015-08-02
    • 2014-01-06
    • 2017-11-02
    • 2022-11-01
    • 2021-12-24
    • 2014-09-30
    • 1970-01-01
    • 2016-02-17
    相关资源
    最近更新 更多