( 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}}}
感谢
答案 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}}}
......这就是我认为你想要的。