By copying the list and then repeatedly replacing part of it:
list = Symbol /@ CharacterRange["a", "n"];
result = list;
result[[{4, 9, 2}]] = Style[#, Red] & /@ result[[{4, 9, 2}]];
result[[{3, 5, 7}]] = Style[#, Green] & /@ result[[{3, 5, 7}]];
result[[{8, 1, 6}]] = Style[#, Blue] & /@ result[[{8, 1, 6}]];
result
(* result is now same as question output *)
This could be put in a function to save some typing:
MapAtMany::usage = "MapAtMany[{{f1, {i1, j1, ...}}, {f2, {i2, j2, ...}}, ...}, expr]";
MapAtMany[fpart_, expr_] := Module[{res = expr},
Scan[
(res[[ #[[2]] ]] = #[[1]] /@ res[[ #[[2]] ]]) &
, fpart];
res];
list = Symbol /@ CharacterRange["a", "n"];
fpart = {
{Style[#, Red] &, {4, 9, 2}},
{Style[#, Green] &, {3, 5, 7}},
{Style[#, Blue] &, {8, 1, 6}}};
MapAtMany[fpart, list]
Fold
can also be used so you don't have to refer to %
for each successive function:
Fold[
MapAt[#2[[1]], #1, Transpose@{#2[[2]]}] &,
list,
fpart
]
Although tests suggest that the Fold
method is much slower and worse at scaling.