Here's a 5x5 grid. Using predefined starting points, I'd like to change some sublists into something else (e.g., the values for a color, "drawing an opaque box").
list =
{{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}};
This seems simple enough, use the Part command to change all of the elements via:
Part[{list}, startingrow;;endingrow, startingelement;;endingelement] = assignment;
(Now use the new list for whatever you like)
This works totally as expected if your list is just a bunch of integers. Trying the one above...
list =
{{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}};
color1 = {0.529`, 0.808`, 0.922`};
row = 3;
start = 2;
Part[list, row - 1 ;; row + 1, start ;; start + 2] = color1;
list
(* Output:
{{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, 0.529, 0.529, 0.529, {1, 1, 1}},
{{1, 1, 1}, 0.808, 0.808, 0.808, {1, 1, 1}},
{{1, 1, 1}, 0.922, 0.922, 0.922, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}}
*)
Not good! The Part function replaced the sublists with each element of the new sublist. Putting the new sublist into a lower level almost works:
Part[list, row - 1 ;; row + 1, start ;; start + 2] = {color1};
list
(* Output:
{{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {1, 1, 1}},
{{1, 1, 1}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {1, 1, 1}},
{{1, 1, 1}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {{0.529, 0.808, 0.922}}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}}
*)
But now all the new sublists are a level too far down. Both Flatten with 2 arguments and FlattenAt don't appear to be able to rid specifically only these levels.
Is there a convenient way to get the desired output? (Shown Below)
{{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}},
{{1, 1, 1}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {1, 1, 1}},
{{1, 1, 1}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {1, 1, 1}},
{{1, 1, 1}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {0.529, 0.808, 0.922}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}}
Part
assign, as a rule you should assign something that's not a list at all or an array that has the same dimensions as thePart
your overwriting. If you do anything else, you should expect things like this to happen. $\endgroup$ – Sjoerd Smit Jul 31 '20 at 19:05