# Conditionally replace rows in lists

I have a sequence of matrices/lists

testlist = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4},
{81, 71, 5}, {80, 70, 6}, {79, 69, 7}, {78, 68, 8},
{77, 67, 9}, {76, 66, 10}, {75, 65, 11}};
Table[list[H1R] = DeleteCases[testlist, a_ /; a[[1]] <= H1R || a[[2]] >= H1R],
{H1R, 80, 78, -1}
]


namely

list[80] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5}}
list[79] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5},
{80, 70, 6}}
list[78] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5},
{80, 70, 6}, {79, 69, 7}}


Now I'd like to be able to, in one shot, using Table or something, in all lists replace all records/rows where say the second element is between 74.5 and 72.3 with a replacement row say {-10,5,0.3}

So at the end of my one shot operation or Table, I'll have:

list[80] = {{85, 75, 1}, {-10,5,0.3}, {-10,5,0.3}, {82, 72, 4},
{81, 71, 5}}
list[79] = {{85, 75, 1}, {-10,5,0.3}, {-10,5,0.3}, {82, 72, 4},
{81, 71, 5}, {80, 70, 6}}
list[78] = {{85, 75, 1}, {-10,5,0.3}, {-10,5,0.3}, {82, 72, 4},
{81, 71, 5}, {80, 70, 6},  {79, 69, 7}}


These lists that I have generated for my example are very similar to each other but my actual lists are quite different and are non-integer and basically I would like to be able to scan all of the lists in one shot and replace certain rows by other rows provided the elements of the rows or functions of elements of the said row fall in some interval.

Second Update:

Mimicking what you guys have done, I did this because I didn't want to write {,.._} because I have 15 columns now and I might have more later:

Table[list[i]=list[i] /. a_ :> {-10, 5, 0.3} /;Dimensions[a] == {3} && 72.3 < a[[2]] < 74.5, {i, 78, 80}]


This code works. woohoo!!

Replace[#, {_, _?(72.3 <= # <= 74.5 &), _} :> {-10, 5, 0.3}, Infinity] & /@
{list[80], list[79], list[78]}

(*{{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71,  5}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81,71, 5}, {80, 70, 6}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}, {79, 69, 7}}}  *)


or ReplaceAll

  {list[80], list[79], list[78]} /. {_, _?(72.3 <= # <= 74.5 &), _} :> {-10, 5, 0.3}


Update: More generally,

rplc[k_, from_, to_, rplcmnt_] :=
Replace[#, {Repeated[_, {k - 1}], _?(from <= # <= to &), ___} :>
rplcmnt, Infinity] & /@ {##} &
(* replace an element with x if its 3rd element is between 3 and 5 :*)
rplc[3, 3, 5, x][list[80], list[79], list[78]]
(* {{{85, 75, 1}, {84, 74, 2}, x, x, x},
{{85, 75, 1}, {84, 74, 2}, x, x,  x, {80, 70, 6}},
{{85, 75, 1}, {84, 74, 2}, x, x,  x, {80, 70, 6}, {79, 69, 7}}} *)

• Thanks Kguler and R.M.! You guys rock! I can't wait to get competent at this stuff so I can help others like everyone here has helped me. Sep 19, 2012 at 4:20
• @Amatya That's the best way to give back to the community :) Good luck!
– rm -rf
Sep 19, 2012 at 4:23
• Hey guys, quick question.. what if the number of columns in my matrix is very large so that it's not feasible to write {,.._}. Is there some way to write check the kth coordinate where k is also a variable that I can alter depending on the situation? Sep 19, 2012 at 4:30
• @Amatya, thanks for the accept. You can use {Repeated[_,k-1],_?(cond),___} instead of {_,_?(cond),_} to cover the more general case where the cond is tested on the kth entry of each sublist. Similarly, {Repeated[_,k-1],x_,___} should work in R.M's method.
– kglr
Sep 19, 2012 at 4:57
• @Kguler thanks! I will do that. I had temporarily unaccepted the answer because I thought I needed to do that for anyone to notice the edit. Sep 19, 2012 at 5:00

Here's another solution using ReplaceAll and Condition:

Table[list[i] /. {_, x_, _} :> {-10, 5, 0.3} /; 72.3 < x < 74.5, {i, 78, 80}]

(* {{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}, {79, 69, 7}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}}} *)

list[80] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5}};

list[79] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5},
{80, 70, 6}};

list[78] = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5},
{80, 70, 6}, {79, 69, 7}};


Using ReplacePart:

rules = Position[#, x_List /; Between[x[[2]], {72.3, 74.5}]] -> {-10, 5, 0.3} &;

ReplacePart[#, rules@#] & /@ {list[80], list[79], list[78]} // Column[#, Spacings -> 1] &


• +1, nice employment of ReplacePart
– eldo
Feb 24 at 15:45

A variant of E. Chan-López positional solution

a = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5}};

b = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}};

c = {{85, 75, 1}, {84, 74, 2}, {83, 73, 3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}, {79, 69, 7}};

m = {a, b, c};


Replacement positions

p = Position[True] @ Map[Between[{72.3, 74.5}], #[[All, 2]]] & /@ m


{{{2}, {3}}, {{2}, {3}}, {{2}, {3}}}

Using ReplaceAt (new in 13.1)

MapThread[ReplaceAt[#1, _ :> {-10, 5, 0.3}, #2] &, {m, p}]


returns

{{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}},
{{85, 75, 1}, {-10, 5, 0.3}, {-10, 5, 0.3}, {82, 72, 4}, {81, 71, 5}, {80, 70, 6}, {79, 69, 7}}}