Delete efficiently rows of empty list elements inside a list
Here is a very simple and concise construct for doing what you ask.
a =
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}},
{{}, {}, {}},
{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}};
a //. {} -> Nothing
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}, {{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}}
It has the advantage of working for { }
appearing at any level.
b =
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}},
{{}, {}, {}},
{{}, {{{}, {{}}, {}}}, {}}};
b //. {} -> Nothing
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}}
Note that I used the very useful new symbol Nothing
. This means the above solution only works for V10.2 or later.
For arbitrarily nested lists one could also use MapAll
and the operator form of DeleteCases
:
b = (* m_goldberg's example *)
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}},
{{}, {}, {}},
{{}, {{{}, {{}}, {}}}, {}}};
DeleteCases[{}] //@ b
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}}
It works via the bottom-up standard evaluation order.
This however is somewhat slower than //.
in a single test. Using an anonymous function instead of the operator form is a little faster than //.
however in the same test, though less clean:
DeleteCases[#, {}] & //@ b
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}}
I don't have the same interpretation of OP requirements as others seem to, but here's my take on those interpretations:
DeleteCases[#, Nest[{# ...} &, {}, Depth[#]], Infinity] &@b
Where b is of course the target list.
Unless Nothing
performs much faster than the use of Sequence[]
, this seems to do quite well against what appears to be the fastest "get rid of any empty list anywhere" solution.
Edit: I used this to generate test b:
b =
RandomChoice[
{9, 1, 1, 1, 9} ->
{{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}},
{{}, {}, {}}, {{}, {{{}, {{}}, {}}}, {}}, {{}},
{{1, 2, 3}, {}, {{{{{{{{{{{{1, 2, 3, {{{}, {1, 2, 3}}}}}}}}}}}}}}},
{1,2, 3, {}}}}, 1000000];