# 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[1]]]],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[[1]]]]] &, 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}]


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

ArrayReshape[Map[Flatten@Append[#[[1]], #[[2]]] &, 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

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]

a = {{{2, 0}, {2, 3}}, {{5, 3}, {4, 0}}, {{0, 5}, {0, 0}}};

b = {1, 2, 3};


Using MapThread

MapThread[Flatten /@ Thread[{##}] &, {b, a}]


Using ReplaceAll with a counter

Module[{i = 1}, a /. {{a__}, {b__}} :> {{i, a}, {i++, b}}]


UsingReplace with MapIndexed

Replace[
MapIndexed[List, a, {2}],
{{a_, b_}, {i_, _}} :> {i, a, b},
{2}]


All produce

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