# How can I add or remove the element in the sub-lists, whose length are different?

If there are lists with different lengths of sublists like below,

list1 = {{{1, 2, 3, 4}, {11, 12, 13, 14}, {22, 23, 24, 25}}, {{-1, -2, -3, -4}, {-11,-12,-13, -14}, {-22, -23, -24, -25}, {-41, -42, -43,-44}}, {{100, 200, 300, 400}, {-100, -200, -300, -400}}}


How can I combine or delite each element from sublists?Question 1. I have another data of

list2 = {a1, a2, a3},


correspond to list1.So I want to combine list2 to each sub element of
list1;

newlist = {{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}}, {{-1, -2, -3, -4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2}, {-41, -42, -43, -44, a2}},{{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}


How can I get newlist? I know I can append a1 to lsmall,

lsmall = {{1, 2, 3, 4}, {11, 12, 13, 14}, {22, 23, 24, 25}}


by

Append[lsmall[[#]], {a1}] & /@ Range[Length[lsmall]]


However newlist cannot get by

Append[lsmall[[#1, #2]], {list2[[#1]]}] & /@ [Range[Length[lsmall]], [Range[Length[lsmall[[#1]]]]]


... I' m in trouble.

Question2 After I get

newlist = {{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}}, {{-1, -2, -3,-4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2}, {-41, -42, -43, -44, a2}},{{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}


in Question 1, I also want to extract 2 dimensional sub lists, such as

ext1 = {{{1, a1}, {11, a1}, {22, a1}}, {{-1, a2}, {-11, a2}, {-22, a2}, {-41, a2}},{{100, a3}, {-100, a3}}}


... (combination of 1 st and last element) or

ext2 ={{{2, 3}, {12, 13}, {23, 24}}, {{-2, -3}, {-12, -13}, {-23, -24}, {-42, -43}},{{200, 300}, {-200, -300}}}


... (combination of 2 nd and 3 rd element)

I thought

For[i = 1, i <= Length[newlist], i++,
For[j = 1, j <= Length[newlist[[i]]], j++,
ext1 = Transpose[{newlist[[i]][[j]][[All, 1]],
newlist[[i]][[j]][[All, 1]]}];]] Return[ext1]


But it didn't work at all.

Here is one way. First I add a zero to the end of each subarray, then I can use Part ([[ ]]) to easily address and update those elements:

list1 = Map[Append[0], list1, {2}];
list1[[All, All, -1]] = list2;
list1


{{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}}, {{-1, -2, -3, -4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2}, {-41, -42, -43, -44, a2}}, {{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}

list1[[All, All, {1, -1}]]


{{{1, a1}, {11, a1}, {22, a1}}, {{-1, a2}, {-11, a2}, {-22, a2}, {-41, a2}}, {{100, a3}, {-100, a3}}}

list1[[All, All, {2, 3}]]


{{{2, 3}, {12, 13}, {23, 24}}, {{-2, -3}, {-12, -13}, {-23, -24}, {-42, -43}}, {{200, 300}, {-200, -300}}}

As you can see, extracting elements is pretty easy. The first step is the hard part. Here is another, more idiomatic, solution to that problem:

MapThread[Append[#2] /@ # &, {list1, list2}]


It may help to think about this problem in two steps. First we need to associate each element in list2 with each element in list1. Then we need to insert the associated elements from list2 into the lists from list1 that they are associated with. The first of these two parts can be done using Transpose, and then we can write a function to do the second part:

f[{l_, x_}] := Append[x] /@ l
f /@ Transpose[{list1, list2}]


This solution is not serious by any means but it represents another approach to the problem in case you're interested:

TakeList[
Append, {
Flatten[list1, 1],
}],
Length /@ list1
]

• Thank you VERY much for your kind explanation!! Now I can get what I want, not only for list1 and list2 but also for other lists. Though it was difficult for me to understand the last part: Catenate@MapThread[ConstantArray, {list2, Length /@ list1}], except this, I got the points. Thanks again! Jul 3, 2020 at 7:16
• @nancy yeah, it's a bit difficult to read which is one reason it shouldn't be the first way to solve the problem. It turns {a, b, c} into {a, a, a, b, b, c, c, c} where the number of each element is the number of corresponding sublists in list1. We then flatten list1 so we now have one list of sublists (no nesting). Now we can easily match the elements to each other. Then we do the reverse using TakeList, i.e. take the flat list and make it multidimensional again. You're welcome! Jul 3, 2020 at 7:32
• I'm really greatful to you, thank you so much. Your comment enhanced my understanding. The point became clear. I think this answer will be helpful to those who have similar question! Jul 3, 2020 at 15:28
newlist = MapThread[Thread[Join[#1, {#2}]] &, {list1, list2}]


{{{1, 11, 22, a1}, {2, 12, 23, a1}, {3, 13, 24, a1}, {4, 14, 25, a1}}, {{-1, -11, -22, -41, a2}, {-2, -12, -23, -42, a2}, {-3, -13, -24, -43, a2}, {-4, -14, -25, -44, a2}}, {{100, -100, a3}, {200, -200, a3}, {300, -300, a3}, {400, -400, a3}}}

ext1 = MapThread[Thread[{First /@ #1, #2}] &, {list1, list2}]


{{{1, a1}, {11, a1}, {22, a1}}, {{-1, a2}, {-11, a2}, {-22, a2}, {-41, a2}}, {{100, a3}, {-100, a3}}}

ext2 = Map[#[[2 ;; 3]] &, list1, {2}]


{{{2, 3}, {12, 13}, {23, 24}}, {{-2, -3}, {-12, -13}, {-23, -24}, {-42, -43}}, {{200, 300}, {-200, -300}}}

• Thank you for telling me how to get ext1 and ext2, directly. For ext2 script, I could also get the conbination of 1st and 4th elements:{{{1, 4}, {11, 14}, {22, 25}}, {{-1, -4}, {-11, -14}, {-22, -25}, {-41, -44}}, {{100, 400}, {-100, -400}}}, by ext2 = Map[{#[[1]], #[[4]]} &, list1, {2}] Jul 3, 2020 at 7:29
ClearAll[f0]
f0 = Inner[#2 /@ # &, #, Append /@ #2, {##} &] &;;

f0[list1, list2]

{{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}},
{{-1, -2, -3, -4, a2}, {-11, -12, -13, -14,  a2}, {-22, -23, -24, -25, a2},
{-41, -42, -43, -44, a2}},
{{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}

% == newlist

True

• Thank you for your answer! I tried the script and successfully got newlist. Jul 3, 2020 at 7:22
a =
{{{1, 2, 3, 4}, {11, 12, 13, 14}, {22, 23, 24, 25}},
{{-1, -2, -3, -4}, {-11, -12, -13, -14}, {-22, -23, -24, -25}, {-41, -42, -43, -44}},
{{100, 200, 300, 400}, {-100, -200, -300, -400}}};

b = {a1, a2, a3};


Using MapApply (new in 13.1)

MapApply[Append[#1] /@ #2 &] @ Transpose[{b, a}]


returns

{{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}},
{{-1, -2, -3, -4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2}, {-41, -42, -43, -44, a2}},
{{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}

l1 = {{{1, 2, 3, 4}, {11, 12, 13, 14}, {22, 23, 24, 25}},
{{-1, -2, -3, -4}, {-11, -12, -13, -14}, {-22, -23, -24, -25},
{-41, -42, -43, -44}}, {{100, 200, 300, 400}, {-100, -200, -300, -400}}};

l2 = {a1, a2, a3};


Using Thread and ReplaceAll:

Thread@*Reverse /@ Thread[{l2, l1}] /. {x_?VectorQ, s_} :> Join @@ {x, {s}}

(*{{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}},
{{-1, -2, -3, -4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2},
{-41, -42, -43, -44, a2}}, {{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}*)


Using MapIndexed:

list1 = {{{1, 2, 3, 4}, {11, 12, 13, 14}, {22, 23, 24,
25}}, {{-1, -2, -3, -4}, {-11, -12, -13, -14}, {-22, -23, -24, \
-25}, {-41, -42, -43, -44}}, {{100, 200, 300,
400}, {-100, -200, -300, -400}}}

list2 = {a1, a2, a3}

f = Map[Append[list2[[First@#2]]], #1] &;
MapIndexed[f, list1]


Result:

{{{1, 2, 3, 4, a1}, {11, 12, 13, 14, a1}, {22, 23, 24, 25, a1}}, {{-1, -2, -3, -4, a2}, {-11, -12, -13, -14, a2}, {-22, -23, -24, -25, a2}, {-41, -42, -43, -44, a2}}, {{100, 200, 300, 400, a3}, {-100, -200, -300, -400, a3}}}