# How to replace matrix entries with certain elements from list of lists of varying length

I have a table ("editp6") of 100 lists, of varying (even) sizes, including an empty list. Each list contains only Integers and Reals, or nothing. Below are the first 3 lists

{{1, 0.04, 8, 11.11, 14, 72.21}, {46, 1247.25, 6, 20.59, 13,
64.94}, {66, 54.18, 31, 166.8, 45, 1561.45}}


I need to replace entries in a 100x100 distance matrix ("Q"), where all entries are initially Infinity, with the corresponding element from editp6 (should such a corresponding element exist), such that the {i,j}-th entry of Q is replaced by the editp6[[i,k+1]] element, where editp6[[i,k]]==j-1, and initial value of k=1, increasing in steps of 2, up to Length[editp6[[i]]].

e.g. from above lists, Q[[2,47]] should be replaced with 1247.25, because editp[[2,1]]+1==j=47 and 1247.25 is the k+1 element of list i=2 where k=1. Q[[3,32]] should be replaced with 166.8, because editp[[3,3]]+1==j=32, and 166.8 is the k+1 element of list i=3 where k=3.

I have made a few attempts to get this to work with Do, For and If loops and using the ReplacePart function, to no avail. I am a beginner with coding and Mathematica, but any help is appreciated.

• Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. Mar 12, 2022 at 19:29

One strategy would be to build up a set of replacement rules and then use ReplacePart on Q. Here's your initial list:

list = {{1, 0.04, 8, 11.11, 14, 72.21}, {46, 1247.25, 6, 20.59, 13, 64.94}, {66, 54.18, 31, 166.8, 45, 1561.45}}


Every adjacent pair is almost a replacement rule. It's just missing the "row" index. So, maybe some combination of Partition (to explicitly pair things up) and then MapIndexed to add in the "row" index.

We could partition your list directly with Partition if it were rectangular (and there may be some fancy way to still do that), but I'll just map Partition over your list.

replacements =
Flatten[
MapIndexed[{#2[[1]], 1 + #1[[1]]} -> #1[[2]] &, Partition[#, 2] & /@ list, {2}]]
(* outputs {{1, 2} -> 0.04, {1, 9} -> 11.11, {1, 15} -> 72.21, {2, 47} -> 1247.25, {2, 7} -> 20.59, {2, 14} -> 64.94, {3, 67} -> 54.18, {3, 32} -> 166.8}*)


Q = ConstantArray[Infinity, {100, 100}];


You could just do the replacements and store it into a new variable, or you could overwrite Q, like this:

Q = ReplacePart[Q, replacements];


Double check:

Q[[2, 47]] (*1247.25*)
Q[[3, 32]] (*166.8*)


A list "of varying (even) sizes, including an empty list":

list =
{{1, 4, 2, 11, 4, 72},
{2, 14, 4, 20},
{},
{1, 54, 2, 16, 3, 15},
{3, 99}};


Using ReplacePart and SequenceCases to create the replacement rules

r = Join @@
ReplacePart[list, i_ :> SequenceCases[list[[i]], {a_, b_} :> {i, a + 1} -> b]]


gives

{{1, 2} ->  4, {1, 3} -> 11, {1, 5} -> 72,
{2, 3} -> 14, {2, 5} -> 20, {4, 2} -> 54,
{4, 3} -> 16, {4, 4} -> 15, {5, 4} -> 99}


Apply r to 5x5 matrix

ReplacePart[Array[0 &, {5, 5}], r] // MatrixForm


list =
{{1, 4, 2, 11, 4, 72},
{2, 14, 4, 20},
{},
{1, 54, 2, 16, 3, 15},
{3, 99}};


Grabbing the @eldo's example and using Do and While:

updateQ[editp6_List, Q_] := Module[{Q2, i, j, k},
Q2 = Q;
Do[
k = 1;
While[k <= Length[editp6[[i]]],
j = editp6[[i, k]] + 1;
If[j <= Length@Q2,
Q2[[i, j]] = editp6[[i, k + 1]]
];
k += 2;
],
{i, Length[editp6]}
];
Q2
]


Testing updateQ:

updateQ[list, ConstantArray[0, {5, 5}]] // TeXForm


$$\left( \begin{array}{ccccc} 0 & 4 & 11 & 0 & 72 \\ 0 & 0 & 14 & 0 & 20 \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 54 & 16 & 15 & 0 \\ 0 & 0 & 0 & 99 & 0 \\ \end{array} \right)$$