如何在使用DeleteCases时删除额外的{}

时间:2011-12-29 09:29:09

标签: wolfram-mathematica

Mathematica 版本:8.0.4)

鉴于

lst = {{{{1, 2}, 3}, {{4, 5}, 6}}, {{{7, 8, 9, 10, 11}, 13}}};
lst2 = DeleteCases[lst, {x_, y_} /; y > 6, {2}]

给出

{{{{1, 2}, 3}, {{4, 5}, 6}}, {}}

注意最后的额外空{}

我找不到使用DeleteCases在同一命令中删除它的方法(我认为这是正确的命令),所以我不得不在结果上再次应用它

lst2 = DeleteCases[lst2, {}]

{{{{1, 2}, 3}, {{4, 5}, 6}}}

问题:有没有诀窍在一个命令中执行上述操作而不在结果中获得空{}?这样命令对所有情况都是自包含的吗?

更新1

回复下面的Lou建议,添加额外的{ }

以下是我得到不同结果的示例:

lst={{{{1, 2}, 3}, {{4, 5}, 6}}, {{{7, 8, 9, 10, 11}, 13}}}

现在使用{}的额外应用删除空DeleteCases的方法,我们得到

lst2 = DeleteCases[lst, {x_, y_} /; y >= 6, {2}]
{{{{1, 2}, 3}}, {}}

lst2 = DeleteCases[lst2, {}]
{{{{1, 2}, 3}}}

现在使用额外{ }

的方法
lst2 = DeleteCases[lst, {{x_, y_}} /; y >= 6]
{{{{1, 2}, 3}, {{4, 5}, 6}}}

这是不一样的,我应该只得到{{{{1, 2}, 3}}}

感谢

6 个答案:

答案 0 :(得分:6)

似乎没有一般的自动方法来删除由于DeleteCases或其他结构转换函数而出现的空列表,作为原始结构操作的一部分。他们的移除必须是一个单独的操作。这个问题:

efficient-way-to-remove-empty-lists-from-lists

回答如何在事实之后有效地做到这一点

答案 1 :(得分:5)

我认为您原来的解决方案是一个很好的解决方案:

$lst = {{{{1, 2}, 3}, {{4, 5}, 6}}, {{{7, 8, 9, 10, 11}, 13}}};

DeleteCases[$lst, {x_, y_} /; y > 6, {2}] // DeleteCases[#, {}] &

清晰简洁。另一种选择是:

DeleteCases[$lst, {x_, y_} /; y > 6, {2}] /. {} -> Sequence[]

然而,让我们坚持下去并尝试通过DeleteCases的单一调用找到一种方法来完成这项工作。我们可以添加一个替代模式,该模式匹配仅包含被拒绝的子对的顶级元素:

DeleteCases[
  $lst
, (a:{{_, _?NumericQ}..} /; And @@ Map[#[[2]] > 6 &, a, {1}]) |
  ({_, y_?NumericQ} /; y > 6)
, {1, 2}
]

两次写入阈值(6)是不方便的。我们可以避免这种情况:

DeleteCases[
  $lst
, 6 /. n_ :>
    (a:{{_, _?NumericQ}..} /; And @@ Map[#[[2]] > n &, a, {1}]) |
    ({_, y_?NumericQ} /; y > n)
, {1, 2}
]

或者,我们可以定义一个匹配顶级元素和单个子对的本地函数:

Module[{test}
, test[elems:{{_, _?NumericQ}..}] := And @@ test /@ elems
; test[{_List, y_?NumericQ}] := y > 6
; DeleteCases[$lst, e_?test, {1, 2}]
]

虽然这些提案只满足了DeleteCases一次调用的要求,但我发现它们并不令人满意。我的主要反对意见是它们不像原始解决方案那样可读。

答案 2 :(得分:2)

lst2 = DeleteCases[DeleteCases[lst, {x_, y_} /; y > 6, {2}], {}] 

答案 3 :(得分:1)

lst2 = DeleteCases[lst, {{x_, y_}} /; y > 6]

但我想你想要将第一个列表与...匹配? 也许:

lst2 = DeleteCases[Flatten[lst,1], {x_, y_} /; y >= 6]

导致{{{1,2},3}}

答案 4 :(得分:1)

其他答案都非常好,我对此回复犹豫不决。

以下只是为了好玩,仅此而已:

lst = {{{{1, 2}, 3}, {{4, 5}, 6}}, {{{7, 8, 9, 10, 11}, 13}}};

使用Cases

Cases[lst, {x_, y_} /; ! y > 6, {2}]

Cases[lst, {x_, y_} /; ! y >= 6, {2}]

  

{{{1,2},3},{{4,5},6}}

     

{{{1,2},3}}

答案 5 :(得分:0)

为什么不在DeleteCases中使用OR子句并根据模式OR {}

进行删除
DeleteCases[lst, {x_, y_} /; y > 6 | {}, {2} ]

在我的机器上返回结果:

{{{{1, 2}, 3}, {{4, 5}, 6}}, {{{7, 8, 9, 10, 11}, 13}}}

......这就是我认为你想要的。