# count conditional items in list

I have a list of the form:

{1,1, (1 if x>y, -1 if y>=x), -1}

I want to count the number of 1's in the list. The output I'm looking for is something of the form:

3 if x>y

2 if y>= x

How can I achieve this?

• I take it that you execute a function to check if x>y and then if the list is already in that form, Count[list, 1] should work. Clarity is needed as to how the list looks like. Apr 1, 2020 at 17:50
• Thanks for your comment! The problem is that I don't want to evaluate the condition. I want it to give me a list of counts and symbolic conditions. Apr 1, 2020 at 17:55
• But that list as it is cannot be evaluated, right? How do you encode the information that if and else part in the list. I mean I want to just know how have you really stored that list. Apr 1, 2020 at 17:59
• Oh I see. The list is literally of the form in the question, such that some of the entries are piecewise functions. This is why just using Count[list,1] doesn't work---it ignores every entry that is a piecewise expression. Apr 1, 2020 at 18:03

countPW[ls_, pat_] :=  Module[{
cf = MapAt[Count[Flatten@#, pat] &, #, {{1, ;;, 1}, {2}}] &,
pwe = PiecewiseExpand[Append[Cases[_If]@ls, Cases[Except[_If]]@ls]]},
PiecewiseExpand[#, Method -> {"ConditionSimplifier" -> FullSimplify}] & @ cf @ pwe]


Examples:

list1 = {1, 1, If[x > y, 1, -1], -1};

countPW[list1, -1 | 1]

4

countPW[list1, 1] // TeXForm


$$\begin{cases} 2 & x\leq y \\ 3 & \text{True} \end{cases}$$

countPW[list1, -1] // TeXForm


$$\begin{cases} 2 & x\leq y \\ 1 & \text{True} \end{cases}$$

list2 = {1, 1, If[x > y, 1, -1], If[z > w, 1, -1], -1};

countPW[list2, -1 | 1]

5

countPW[list2, 1] // TeXForm


$$\begin{cases} 2 & x\leq y\land w\geq z \\ 3 & \neg (w

countPW[list2, -1] // TeXForm


$$\begin{cases} 3 & x\leq y\land w\geq z \\ 2 & \neg (w

list3 = {1, 1, 2, If[x > y, {1, 2, 3, -1}, -1], If[z > w, {1, 3, 4}, {2, 2, -1}], -1};

countPW[list3, 2 | -1] // TeXForm


$$\begin{cases} 3 & x\leq y\land wy\land w

• this is AWESOME, thank you!!! Apr 2, 2020 at 13:35

If the conditional expression is written in the Mathematica form

expr = {1, 1, If[x > y, 1, -1], -1, If[x > y, 1, -1], -1};


then we could define a function

Clear[count]
count[expr_, patt_] := Block[{cond, alt1, alt2},
{cond, alt1, alt2} =
FirstCase[expr, item_If :> List @@ item];
If[cond,
Evaluate[Count[expr /. cond :> True, patt]],
Evaluate[Count[expr /. cond :> False, patt]]]
]


which counts the patterns in the conditional expression

count[expr, 1]
(*  If[x > y, 4, 2]  *)

count[expr, -1]
(*  If[x > y, 2, 4]  *)


Note that count assumes, but does not check for, identical first arguments of each If.

In no way is this the best solution, but this does the job.

l = Piecewise[{{1, x > y}, {-1, x <= y}}]

list = RandomChoice[{1, -1, l}, 5]
(*{Piecewise[{{1, x > y}, {-1, x <= y}}], -1, 1, Piecewise[{{1, x > y}, {-1, x <= y}}], -1}*)

Count[Assuming[#, Refine /@ list], 1] & /@ {x > y, x <= y}
(*3,1*)