What is the most efficient way to remove all empty List[]
objects from all of the List
s that appear in an expression at different levels? The empty List[]
should be removed only if it is an element of another List
itself.
相关问题
- Puzzled by Function body evaluation
- how to overload Times and Plus for matrix multipli
- AOSP Build TARGET_PRODUCT fails
- Modifying a Graphics3D object generated by Paramet
- Mathematica “AppendTo” function problem
相关文章
- histogram without vertical lines in Mathematica
- Entering data with Input[] in mathematica
- Using Fold to calculate the result of linear recur
- How should I write a function to be used in Apply
- NMinimize eats all memory b/c of unnecessary symbo
- Mathematica: set default value for argument to non
- how does mathematica determine which rule to use f
- Animate the movement of a point along the plot of
Andrew and Alexey point out that using
expr //. x_List :> DeleteCases[x, {}, Infinity]
as I had in my previous answer will also remove the{}
inblah[{f[{}]}]
, whereas it should leave it untouched as its head isf
, not aList
. The solution, thanks to Leonid, is to not useReplaceRepeated
, butReplace
instead with replacements being made at all levels from0
throughInfinity
:The reason why
Replace
works andReplaceRepeated
doesn't can be seen from this little example. Considerexpr = {a, {}, {b, {}}, c[d, {}]};
in itsTreeForm
Replace
works by starting with the innermost expression(s) first, i.e.,List[b,{}]
andc[d,{}]
, and works upwards to the top node. At each level, checking the head is as simple as looking up to the node right above and see if it matchesList
. If it does, apply the rule and move up a level, else do nothing and move up a level. This results in a final tree:ReplaceRepeated
(//.)
, on the other hand, works by starting with the top most node and traversing down the tree. The previous solution starts by checking if the first node is aList
and if it is, thenDeleteCases
is applied and it moves down the tree, ruthlessly replacing every{}
it can find. Note that it does not check if the heads of the inner expressions also matchList
, because this traversal is done byDeleteCases
, notReplaceRepeated
. When//.
moves to subsequent lower nodes, there is nothing more to replace and it exits quickly. This is the tree that one gets with the previous solution:Note that the
{}
insidec[d, {}]
has also been removed. This is solely due to the fact thatDeleteCases
(with level specification{0,Infinity}
moves down the tree. Indeed, if the first head had been something other thanList
, it would've skipped it and moved to the next level, of which only the{}
in{b, {}}
is a match. To demostrate withexpr2 = f[a, {}, {b, {}}, c[d, {}]]
, we getNote that in the current solution with
Replace
, we useDeleteCases
with the default level specification, which is the first level only. It does not, therefore, check for and delete empty lists deeper than on the first level, which is exactly what we need here.Although we used the first node to explain why it fails, the reasoning holds true for every node. Leonid explains these concepts in greater detail in his book