3
$\begingroup$

I have a repeatedly nested one-element list, e.g. a={{{{2}}}}. Is there a direct way to pull out the innermost element? I could just do First@Flatten@a, but I feel like there should be an even more straightforward method.

$\endgroup$
2
  • 8
    $\begingroup$ Max@a perhaps? $\endgroup$ – wxffles Sep 13 '16 at 22:12
  • 1
    $\begingroup$ @wxffles Using Max on an empty (nested) list such as Max@{{}} returns -\[Infinity] $\endgroup$ – Sascha Sep 14 '16 at 6:53
3
$\begingroup$

First@Flatten@a can be be annoying since Flatten fails for atomic expressions e.g. when you have non-nested expressions too e.g.

list={{{1}}, {2}, {{{3}}}, 4}
First@*Flatten /@ list
(* Flatten::normal: Nonatomic expression expected at position 1 in Flatten[4]. *)

if you want to avoid this you could for instance use

Apply[Sequence, #, All] & /@ list

Edit: In response to Kuba's comment I though a little more about this and found another "special case" that fails when naively using First@Flatten@a

First@Flatten@{{{}}}
(* First::nofirst: {} has zero length and no first element. *)

An empty (nested) list might occur in the context of flattening some result returned by another function where there is a possibly of not having found a solution/partial solution.

Apply[Sequence, {{{}}}, All] one the other hand simply evaluates to Sequence[] which vanishes upon further evaluation. Another fix for this is of course the new second argument to First

First[#, Nothing[]]&@Flatten@{{{}}}
$\endgroup$
2
  • $\begingroup$ But then the input isn't really a nested list. $\endgroup$ – Kuba Sep 14 '16 at 6:30
  • $\begingroup$ @Kuba I know, but more often than not I end up using something like First@Flatten@a inside some more complex context and have it fail later in some special cases (such as atomic expressions which could one view as being nested with depth 0). $\endgroup$ – Sascha Sep 14 '16 at 6:36
1
$\begingroup$

Probably a matter of taste:

a /. List -> (# &)

I'd go with your method though.

If that element does not have "a structure" you can use e.g. Level[a, {-1}][[1]] for example.

$\endgroup$
0
$\begingroup$

I'll try to wrap up the solutions:

  • if one considers repeatedly nested single-element lists, e.g. {{{2}}}, then Max returns the innermost element; this works also for non-numerical elements like a or "a";
  • when the innermost list is empty, {{{}}}, then Max returns -∞, which may cause problems;
  • First@Flatten gives an error when used on an empty nested list;
  • the safest possibility seems to be to define a new function, elem := First[#, Nothing[]] &@Flatten@#1 &, that works on empty as well as non-empty single-element nested lists - credit for this goes to Sascha.

I did not consider here lists with more than one element, e.g. {{{1,{a}}}}; Max remains unevaluated (unless a is also numerical, but then it just gives the greater element), while First@Flatten and elem return the first element, i.e. 1 in this case. But such lists are not the scope of this question as how to handle them will be different in each particular situation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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