9
$\begingroup$

I have a long list from testing data. It looks like

pts={{{{},{}, ..., {{t1, a1, b1, c1}}, ..., {}},{{},{}, ..., {{ti, ai, bi, ci}}, ..., {}}, ..., {{},{}, ..., {{tj, aj, bj, cj}}, ..., {}}},{{{},{}, ..., {{tk, ak, bk, ck}}, ..., {}},{{},{}, ..., {{tm, am, bm, cm}}, ..., {}}, ..., {{},{}, ..., {{tn, an, bn, cn}}, ..., {}}}, ..., {{{},{}, ..., {{tp, ap, bp, cp}}, ..., {}}, {{},{}, ..., {{tq, aq, bq, cq}}, ..., {}}, ..., {{},{}, ..., {{tl, al, bl, cl}}, ..., {}}}}`

in which all {} are empty lists, generated by Nothing, and the sub-lists like {t, a, b, c} include numerical values t, a, b and c. I have to remove all empty elements and keep those sub-lists with numerical values in the form of

ptsnew={{t1, a1, b1, c1}, {ti, ai, bi, ci}, {tj, aj, bj, cj}, {tk, ak, bk, ck},{tm, am, bm, cm}, {tn, an, bn, cn}, {tp, ap, bp, cp}, {tq, aq, bq, cq}, {tl, al, bl, cl}}`

I have tried DeleteCases[pts, {}, 3], which however only removes the empty list on level-3.

$\endgroup$
2

5 Answers 5

6
$\begingroup$

Try this:

pts = {{}, {}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}}

(*  {{}, {}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}}  *)

pts /. {} -> Nothing

(* {{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}  *)

If you have there nested empty lists you will need to apply the procedure several times. For example, let your list be:

pts = {{{}}, {{{{}}}}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}};

Then the repeated application of the above rule can look as follows:

FixedPoint[ReplaceAll[#, {} -> Nothing] &, pts]

(*  {{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}  *)

Have fun!

$\endgroup$
4
  • $\begingroup$ Please note there are 4 layers of {} before reaching the non-empty elements in my example. Your answer actually give the same result as DeleteCases[pts, {}, 3] for my example. $\endgroup$
    – Nobody
    Commented Dec 25, 2021 at 13:49
  • $\begingroup$ It almost achieves my aim! But as mentioned in my post, pts is a really long list, which even include a skeletonizing OutputSizeLimitSkeleton[100], for example. This makes your method not work for those skeletonized sub-lists. Is there any way to make it take effect into the ignored elements, instead of must clicking show more below the long list to expand it before applying FixedPoint. Thank you very much! $\endgroup$
    – Nobody
    Commented Dec 25, 2021 at 14:09
  • $\begingroup$ I am not familiar with skeletonizing. However, as I see your desired form of the result, maybe a good idea would be to first apply Flatten to the list and then the operation that I proposed. $\endgroup$ Commented Dec 25, 2021 at 14:43
  • 4
    $\begingroup$ Your FixedPoint approach is equivalent to pts //. {} :> Nothing, i.e., using ReplaceRepeated $\endgroup$
    – Bob Hanlon
    Commented Dec 25, 2021 at 15:29
6
$\begingroup$

pts = {{{{}, {}, {{t1, a1, b1, c1}}, {}}, {{}, {}, {{ti, ai, bi, ci}}, {}}, {{}, {}, {{tj, aj, bj, cj}}, {}}}, {{{}, {}, {{tk, ak, bk, ck}}, {}}, {{}, {}, {{tm, am, bm, cm}}, {}}, {{}, {}, {{tn, an, bn, cn}}, {}}}, {{{}, {}, {{tp, ap, bp, cp}}, {}}, {{}, {}, {{tq, aq, bq, cq}}, {}}, {{}, {}, {{tl, al, bl, cl}}, {}}}}

 DeleteCases[pts, {}, Infinity]//Flatten[#, 3]&

enter image description here

An alternative is to use Cases with a pattern that matches the types of the relevant sub lists.

Cases[pts, {_Symbol, _Symbol, _Symbol, _Symbol}, Infinity]

enter image description here

$\endgroup$
5
$\begingroup$
Level[pts, {-2}] /. {} -> Nothing
{{t1, a1, b1, c1}, {ti, ai, bi, ci}, {tj, aj, bj, cj}, {tk, ak, bk, 
  ck}, {tm, am, bm, cm}, {tn, an, bn, cn}, {tp, ap, bp, cp}, {tq, aq, 
  bq, cq}, {tl, al, bl, cl}}
$\endgroup$
2
$\begingroup$

Simple case with Case

a = {{}, {}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}};

Cases[la, {{__?AtomQ}}]

{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}

Nested case with Case

lb = {{{}}, {{{{}}}}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}};

Cases[lb, {{__?AtomQ}}]

{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}

$\endgroup$
1
$\begingroup$
la = {{}, {}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}};

lb = {{{}}, {{{{}}}}, {{t1, a1, b1, c1}}, {}, {{ti, ai, bi, ci}}};

Grabbing the @eldo's examples and using Select:

Select[la, Level[#, {-1}] =!= {} &]

(*{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}*)

Select[lb, Level[#, {-1}] =!= {} &]

(*{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}*)

Or using FixedPoint and DeleteCases:

FixedPoint[DeleteCases[#, {}, ∞] &, la]

(*{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}*)

 FixedPoint[DeleteCases[#, {}, ∞] &, lb]

(*{{{t1, a1, b1, c1}}, {{ti, ai, bi, ci}}}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.