# How to filter list of list of rules on certain condition?

For example, Solve[] returns all solutions as a list of list of rules. And mine looks something like this:

{ {g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3], h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> 0, g[2] -> Sqrt[2] g[3], h[1] -> 0, h[2] -> Sqrt[2] h[3], h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> -2 Sqrt[2] g[3], g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
...... }

I want to select all list of rules in which both g[1] and h[3] don't go to 0. Is there a way to do that?

• The question is unclear, e.g. in the first list there is no limit for g[1]. P.s. Take a look at Select and ReplaceAll. – Kuba Jun 25 '15 at 11:54
• Select seems a good candidate. Try in combination with FreeQ – mikuszefski Jun 25 '15 at 12:01
• @Kuba Thank you. To make it clear, my intention is to select those that didn't assign values or assigned non-zero values or assigned a relation to other variables for g[1], h[3], etc. – Xilin Jun 25 '15 at 12:30
• So you want to remove all that contain g[1] -> 0 and h[3] -> 0 at the same time. Only one would be OK as well as the appearance of g[1] and h[3] in other relations. Is that right? – mikuszefski Jun 25 '15 at 12:37
• @mikuszefski I actually want both of them not go to zero as stated in the original question. But this is not important because if there's a way to apply one constraint( and people here showed me many =P ), I can always apply multiple constraints along with any logic as I want. – Xilin Jun 25 '15 at 13:38

Pick[sols, FreeQ[#, 0, 1] & /@ ({g[1], h[3]} /. sols)]

Where sols is your Solve result.

rules = {{g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0}, {g[1] -> 0,
g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[1] -> 0, g[2] -> -Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> 0, g[2] -> Sqrt[2] g[3],
h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[1] -> 0, g[2] -> Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> -2 Sqrt[2] g[3],
g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0}, {g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}};

Delete[rules,
Join[Position[rules, g[1] -> 0], Position[rules, h[3] -> 0]]]

(* {{g[2] -> g[1], g[3] -> 0, h[1] -> 0}, {g[2] -> -Sqrt[2] g[3],
h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[2] -> -Sqrt[2] g[3], h[1] -> 0,
h[4] -> 0}, {g[2] -> Sqrt[2] g[3], h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[2] -> Sqrt[2] g[3], h[1] -> 0,
h[4] -> 0}, {g[1] -> -2 Sqrt[2] g[3], g[2] -> -3 Sqrt[2] g[3],
h[1] -> 0, h[4] -> 0}, {g[1] -> 2 Sqrt[2] g[3],
g[2] -> 3 Sqrt[2] g[3], h[1] -> 0, h[4] -> 0}}  *)

Have fun!

• Thanks, but deleting the rules from the the list to make them such that they don't contain g[1] -> 0 and h[3] -> 0 is not what I wanted. I meant to select all the lists which don't contain g[1]->0 in the first place. – Xilin Jun 26 '15 at 11:52
• Then you formulate incorrectly, since it is not what stays in your question. – Alexei Boulbitch Jun 26 '15 at 13:05
solns = {
{g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> 0, g[2] -> Sqrt[2] g[3], h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> Sqrt[2] g[3], h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> -2 Sqrt[2] g[3], g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0},
{g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0}
};

DeleteCases[solns, {___, g[1] -> 0, __, h[3] -> 0, ___}]
{{g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> Sqrt[2] g[3], h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]},
{g[1] -> -2 Sqrt[2] g[3], g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0},
{g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0}}
• Is it right that this requires at least one element between g[1] and h[3] (the middle __ a typo? ->___) and (knowing how Mathematica sorts things probably OK) that they appear in that order? – mikuszefski Jun 25 '15 at 12:43
• I see that you interpreted the question is meaning both g[1] -> 0 and h[3] -> 0 must be present in a sublist for it to be removed? I interpreted that if either were present it should be removed. – Mr.Wizard Jun 25 '15 at 12:47
• @Mr.Wizard. Yes, because OP wrote "both g[1] and h[3] don't go to 0" in the question. Needs disambiguating parentheses, I guess, but English doesn't have that feature. Wish it did. – m_goldberg Jun 25 '15 at 14:12
• @mikuszefski. I thought about using ___ , but decided I could get away with just __. It's certainly OK for the posted example. Only OP knows for sure the requirements of the real data. – m_goldberg Jun 25 '15 at 14:16

Your example solutions plus some which don't have either g[1] or h[3] going to zero:

sol = {{g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0}, {g[1] -> 0,
g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[1] -> 0, g[2] -> -Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> 0,
g[2] -> Sqrt[2] g[3], h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[1] -> 0, g[2] -> Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> -2 Sqrt[2] g[3],
g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0}, {g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> 1,
h[3] -> 1, g[2] -> 0}, {h[3] -> 1}};

Using Select and ReplaceAll (/.) as @kuba suggested:

Select[sol, ({g[1], h[3]} /. #) != {0, 0} &]

{{g[1] -> 1, h[3] -> 1, g[2] -> 0}, {h[3] -> 1}}

• Thank you, the answer is helpful. But this doesn't work with cases where g[1] is not assigned a value. I would want to keep those list, but Select doesn't admit them because (I presume) as g[1] is not assigned a value, it could be 0. – Xilin Jun 26 '15 at 11:56
• @Xilin My final example rule set does not include a rule for g[1] yet it is returned by my Select expression so I do not agree with your comment. – MikeLimaOscar Jun 26 '15 at 12:21
• I tried Select[Join[ solution, {{g[1] -> 1, h[3] -> 1, g[2] -> 0}, {h[3] -> 1}, {g[1] -> 2 g[2], h[2] -> 1}}], ({g[1], h[3]} /. #) != {0, 0} &], and it only gives me {{g[1] -> 1, h[3] -> 1, g[2] -> 0}, {h[3] -> 1}} Somehow while it admits your last example, it doesn't admit my new example. It just seems my guess about why it's behaving this way is wrong... – Xilin Jun 26 '15 at 12:25

That would be my version:

rules = {
{g[2] -> g[1], g[3] -> 0, h[1] -> 0, h[3] -> 0},
{g[1] -> 0, g[2] -> -Sqrt[2] g[3], h[1] -> 0, h[2] -> -Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]}, {g[1] -> 0, g[2] -> -Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}, {g[1] -> 0, g[2] -> Sqrt[2] g[3],
h[1] -> 0, h[2] -> Sqrt[2] h[3],
h[4] -> (g[4] h[3])/g[3]},
{g[1] -> 0, g[2] -> Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0},
{g[1] -> -2 Sqrt[2] g[3],
g[2] -> -3 Sqrt[2] g[3], h[1] -> 0, h[3] -> 0,
h[4] -> 0}, {g[1] -> 2 Sqrt[2] g[3], g[2] -> 3 Sqrt[2] g[3],
h[1] -> 0, h[3] -> 0, h[4] -> 0}};

newRules=Select[rules,!(!FreeQ[#,g[1] -> 0]&&!FreeQ[#,h[3] -> 0])&]

...had to play with "logic", though. Hence the negations !.