# Replacing the Zeros of One List by the (i-1)th Element of Another List

My goal is to replace the zeros of one list with the (i-1)th element of a second list. For example, if

list1 = {0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0}


and

list2 = {6, 1, 4, 7, 2, 9, 10, 8, 11, 3, 5, 0, 12}


the desired output is {0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}. Note that the first element of the output is defined as 0 still.

My attempt to create a code for this is to first find the zeros of list1then run a for-loop for $$i \in$$zeroslist1.

zeroslist1 = Flatten[Position[list1, 0]]
DeleteCases[
Flatten[Reap@
Do[Sow[ReplacePart[vtest1,
i -> vtest2[[i - 1]] & /@ zeroslist1]], {i, zeroslist1}], 2], Null]


The results of the output are:

{{List,1,1,0,0,1,1,0,1,0,0,1,0}, {0,1,1,4,0,1,1,0,1,0,0,1,0}, {0,1,1,0,7,1,1,0,1,0,0,1,0},{0,1,1,0,0,1,1,10,1,0,0,1,0}, {0,1,1,0,0,1,1,0,1,11,0,1,0},{0,1,1,0,0,1,1,0,1,0,3,1,0}, {0,1,1,0,0,1,1,0,1,0,0,1,0}}.

Either a cleaner way to code the desire output or a method of merging the output of my current for-loop to get the desired output would be great.

## 5 Answers

You can use a multiplication instead of looping or conditionals:

list1 + (1 - list1) Prepend[Most[list2], 0]


{0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}

The central point is that 0 and 1 in list1 aren't just symbols but numeric quantities.

• What a simple way to do this. Thank you so much. Feb 11, 2019 at 17:51
idx = RandomPrivatePositionsOf[Rest[list1], 0];
result = list1;
result[[idx + 1]] = list2[[idx]];
result


{0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}

Here's another possibility:

Module[{tmp=list1},
With[{i = Pick[Range[Length[list1]-1], Rest @ list1, 0]},
tmp[[i+1]]=list2[[i]]
];
tmp
]


{0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}

Also MapIndexed works fine

(# /. List -> 0) & /@ MapIndexed[Replace[#1, 0 -> list2[[#2[[1]] - 1]]] &, list1]


The first piece just replaces the special case when a zero element is in the first entry (in Mathematica the 0th element is the Head, which in this case is List). Then the function MapIndexed does its job.

MapThread[If[#1 == 0, #2, #1] &, {Join[list1, {0}], Join[{0}, list2]}] // Most


{0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}

Your answer from above

{0, 1, 1, 4, 7, 1, 1, 10, 1, 11, 3, 1, 0}