8
$\begingroup$

I know that I can convert an expression to list by

List @@ expr

But this does not work if expr is atomic, e.g.,

List @@ 1

will give you 1 instead of {1}. Of course I can check the length of expr first. But I wonder if there is simpler way to do this.

$\endgroup$
1
  • 3
    $\begingroup$ "But this does not work if expr contains only one term" - perhaps you meant to say that expr is atomic; List @@ f[1] works fine. $\endgroup$ Commented May 18, 2020 at 12:42

4 Answers 4

12
$\begingroup$

Like J.M. wrote, the question is if the expression is atomic, because Apply doesn't work on atomic expressions. If we disambiguate the two cases we should be fine:

Listify = If[AtomQ[#], {#}, List @@ #]&

Listify[42]
(* {42} *)

Listify[foo[1, 2, 3]]
(* {1, 2, 3} *)
$\endgroup$
9
$\begingroup$
ClearAll[toList]
toList = # /. { _[a__] :> {a}, a_?AtomQ :> {a}} &;

Examples:

list = {2, a, foo[a, b], s + t + u, Rational[1, 3], 
   Complex[5, 6], <|a -> x, b -> y, c -> z|>, DateObject[]};

Grid[Prepend[Transpose[{list, toList /@ list}], 
  Item[#, Background -> LightBlue] & /@ {"expr", "toList@expr"}], 
 Dividers -> All]

enter image description here

$\endgroup$
3
$\begingroup$
list = {42, a, f[1, 2, 3], {1, 2, 3}};

Using Replace

List @@@ Replace[list, x_?AtomQ :> {x}, {1}]

{{42}, {a}, {1, 2, 3}, {1, 2, 3}}

$\endgroup$
3
$\begingroup$
list1 = {42, a, f[1, 2, 3], {1, 2, 3}};

list2 = {2, a, foo[a, b], s + t + u, Rational[1, 3], 
         Complex[5, 6], <|a -> x, b -> y, c -> z|>, DateObject[]};

Grabbing the @eldo's list and using Cases and Map:

list1 // Map[Cases[{#}, x_ /; AtomQ[x], {0, ∞}] &]

(*{{42}, {a}, {1, 2, 3}, {1, 2, 3}}*)

Generalizing the solution:

f1[expr_] := ReleaseHold@HoldForm[Attributes][Head[expr]]

f2[expr_] /; f1[expr] =!= {} && AtomQ[expr] || f1[expr] =!= {} 
          && ! AtomQ[expr] := expr /. s1_[s2__] | s2__ :> {s2}

f2[expr_] /; f1[expr] === {} := Cases[{expr}, x_ /; AtomQ[x], {0, ∞}]

f2 /@ list2 === toList /@ list2

(*True*)
$\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.