# Combining a list with a certain index of a list

I have two lists. One with three levels (list) and a second one (list 2)

list = {{{2, 0}, {2, 3}},
{{5, 3}, {4, 0}},
{{0, 5}, {0, 0}}}
list2 = {1,2,3}


and I want to combine the pairs of each second level from list with list2 to get

listcombined = {{{1, 2, 0}, {1, 2, 3}},
{{2, 5, 3}, {2, 4, 0}},
{{3, 0, 5}, {3, 0, 0}}}


Right now I used Map Indexedwith the following function and got

combine [x_,index_]:={list2[[[index]]],x}
MapIndexed [combine,list,{2}]

{{{{1, {2, 0}}, {1, {2, 3}}},
{{2, {5, 3}}, {2, {4, 0}}},
{{3, {0, 5}}, {3, {0, 0}}}}


To get the desired list I then use first Flatten and two times Partition. Is there also an easier way, which avoids the last three steps?

Here is a direct way using MapIndexed:

MapIndexed[Prepend[#, list2[[#2[]]]] &, list, {2}]


and another way using ReplacePart:

ReplacePart[list, {i_, _, 0} :> ({list2[[i]], ##} &)]


If you reshape list2 to have the same depth as list, you can Join them directly at the deepest level:

Join[
Map[List, Transpose @ ConstantArray[list2, {2}], {2}],
list,
3
]


MapThread[f, {list, list2}]
(* {f[{{2, 0}, {2, 3}}, 1], f[{{5, 3}, {4, 0}}, 2], f[{{0, 5}, {0, 0}}, 3]} *)


So, we've reduced the problem to defining f in a way that prepends its second argument to every member of its first argument. We could do something like this:

PrependToEach[list_, elem_] := Prepend[elem] /@ list


Combine these into:

MapThread[PrependToEach, {list, list2}]


There are also some nifty padding functions, the best one for this case might be ArrayPad. To use it, we need to manipulate list2 into the right form:

ArrayPad[list, {{0, 0}, {0, 0}, {1, 0}}, List@*List /@ list2]


Just for fun, the following puzzle in the form of code works:

ArrayReshape[Map[Flatten@Append[#[], #[]] &, Level[Map[Thread, Thread[Map[Composition[Transpose, List, ConstantArray[#, Mean[Map[Length, list, {1}]]] &], list2] -> list]], {Mean[Map[Length, list, {1}]]}]], MapAt[# + 1 &, Dimensions[list], Last[list2]]]


The result: Or more simple using Table:

Table[Prepend[list[[i, j]], list2[[i]]], {i, 1, Length[list2]}, {j, 1,Mean[Map[Length, list, {1}]]}]
(*{{{1, 2, 0}, {1, 2, 3}}, {{2, 5, 3}, {2, 4, 0}}, {{3, 0, 5}, {3, 0, 0}}}*)

Clear[list1, list2];

list1 = {{{2, 0}, {2, 3}}, {{5, 3}, {4, 0}}, {{0, 5}, {0, 0}}};
list2 = {1, 2, 3};

Transpose[{List /@ list2, list1}]

> {{{1}, {{2, 0}, {2, 3}}}, {{2}, {{5, 3}, {4, 0}}}, {{3}, {{0, 5}, {0,
>     0}}}}


Now use Thread:

res = Thread[Join[First@#, Transpose@Last@#]] & /@
Transpose[{List /@ list2, list1}]

MatrixForm /@ {list2, list1, res}

listcombined == res (*True*) Another solution using Table:

res2 = Table[
Prepend[#, list2[[i]]] & /@ list1[[i]], {i, 1, Length@list1}]

ArrayFlatten[{#}] & /@ Thread[{list2, list}]

(* {{{1, 2, 0}, {1, 2, 3}}, {{2, 5, 3}, {2, 4, 0}}, {{3, 0, 5}, {3, 0, 0}}} *)

% ==listcombined

True


Edit

Because this method is almost identical to a previous answer of mine, I've marked it 'community wiki'. Feel free to edit