3
$\begingroup$

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.

$\endgroup$
5
  • 1
    $\begingroup$ 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)]}) $\endgroup$
    – thorimur
    Sep 21, 2021 at 20:46
  • $\begingroup$ 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 $\endgroup$
    – thorimur
    Sep 21, 2021 at 20:53
  • $\begingroup$ (also, you can define a function with e.g. myfunction[list_] := <the expression above>; search the docs for "defining functions") $\endgroup$
    – thorimur
    Sep 21, 2021 at 21:28
  • $\begingroup$ I get an error message saying: Syntax: "x|" cannot be followed by "->x==Im[x]I&&x!=0". $\endgroup$
    – golden77
    Sep 21, 2021 at 22:29
  • $\begingroup$ 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>] $\endgroup$
    – thorimur
    Sep 22, 2021 at 20:56

3 Answers 3

3
$\begingroup$

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

$\endgroup$
2
$\begingroup$
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}}

$\endgroup$
1
$\begingroup$

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] := 
  Thread[{"PositiveReal", "NegativeReal", "Complex", 
     "Other"} -> (Scan[
        If[Head@# === Real && Positive@#, Sow[#, "PositiveReal"], 
          If[Head@# === Real && Negative@#, Sow[#, "NegativeReal"], 
           If[Head@# === Complex, Sow[#, "Complex"], 
            Sow[#, "Other"]]]] &, k] // Reap // Last)
   ];

f /@ {la, lb} // TableForm

(* same outputs *)

$\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.