# Simple way to convert expression to a list?

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.

• "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. May 18, 2020 at 12:42

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} *)

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]


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}}

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*)