# How to do simple list traversal? And how do I insert this in a function?

I want to make a function that takes as input a list of numbers and returns a list of 4 lists; the first returned list holds all positive real; the second returned list all negative real; the third list holds imaginary numbers; and the fourth list has others. A pretty simple question but I'm quite new to Mathematica.

• something like Through[{Select[Positive], Select[Negative], Select[x |-> x == Im[x] I && x != 0], Select[x |-> x == 0 || (Re[x] != 0 && Im[x] != 0)]}[list]]? (this is equivalent to {Select[list, Positive], Select[list, Negative], Select[list, x |-> x == Im[x] I && x != 0], Select[list, x |-> x == 0 || (Re[x] != 0 && Im[x] != 0)]}) Sep 21, 2021 at 20:46
• in general, Select[list, testf] returns a list of elements x of list for which testf[x] is True; the criteria we're using here are the built-ins Positive and Negative, an anonymous function x |-> ... which checks if its argument equals its imaginary part and isn't 0, and one which checks if it's argument is equal to 0 or has a real and imaginary part both unequal to 0 Sep 21, 2021 at 20:53
• (also, you can define a function with e.g. myfunction[list_] := <the expression above>; search the docs for "defining functions") Sep 21, 2021 at 21:28
• I get an error message saying: Syntax: "x|" cannot be followed by "->x==Im[x]I&&x!=0". Sep 21, 2021 at 22:29
• ah, you're likely on an older version of mathematica, then; for an anonymous function, you'll either need to use #, & syntax, or explicitly Function[x, <body>] Sep 22, 2021 at 20:56

You could define a type function to determine the type, and then use GroupBy:

type[x_] := Which[
!TrueQ @ NumericQ[x],"Other",
Positive[x],"Positive",
Negative[x],"Negative",
True, "Complex"
]

For example:

GroupBy[{1, 2, x, 3 + I, (-1)^(1/3), -BesselJZero[2,2], ZetaZero[2]}, type]

<|"Positive" -> {1, 2}, "Other" -> {x}, "Complex" -> {3 + I, (-1)^(1/3), ZetaZero[2]}, "Negative" -> {-BesselJZero[2, 2]}|>

la = {1., -2., -1., 2., I, 2 + 3 I, 4/3, 2, 0., 0, -3.};

Using Query

Query[Select[MatchQ @ #] & /@
{_Real?Positive,
_Real?Negative,
_Complex,
_Rational | _Integer | 0.}] @ la

{{1., 2.}, {-2., -1., -3.}, {I, 2 + 3 I}, {4/3, 2, 0., 0}}

If we don't want to specify the other elements

lb = {1., -2., -1., 2., I, 2 + 3 I, 4/3, 2, 0., 0, -3., ComplexInfinity, "String"};

lc =
Query[Select[MatchQ @ #] & /@
{_Real?Positive,
_Real?Negative,
_Complex,
_}] @ lb;

Using SymmetricDifference (new in 13.1)

Join[Most @ lc, {SymmetricDifference @@ lc}]

{{1., 2.}, {-2., -1., -3.}, {I, 2 + 3*I}, {0, 0., 4/3, 2, "String", ComplexInfinity}}

Using @eldo's data and writing for improved readability only:

la = {1., -2., -1., 2., I, 2 + 3 I, 4/3, 2, 0., 0, -3.};
lb = {1., -2., -1., 2., I, 2 + 3 I, 4/3, 2, 0., 0, -3.,
ComplexInfinity, "String"};

p1 = _Real?Positive;
p2 = _Real?Negative;
p3 = _Complex;
p4 = Except[p1 | p2 | p3];

Cases[la, #] & /@ {p1, p2, p3, p4}

{{1., 2.}, {-2., -1., -3.}, {I, 2 + 3 I}, {4/3, 2, 0., 0}}

Cases[lb, #] & /@ {p1, p2, p3, p4}

{{1., 2.}, {-2., -1., -3.}, {I, 2 + 3 I}, {4/3, 2, 0., 0, ComplexInfinity, "String"}}

Using Sow/Reap:

f[k_List] :=