# Join lists with nested list

Is there a way of smarter way of joining list of the form

l1 = {a,{b,c}};
l2 = {d,{e,f}};
l3 = {g,{h,i}};


To obtain

{a,d,g,{b,c,e,f,h,i}}


The code I have is

 {Sequence @@ #1, Flatten[#2]} & @@  Transpose[{l1, l2, l3}]


MapThread[Join, {l1, l2, l3}] /. Join -> Sequence


{a, d, g, {b, c, e, f, h, i}}

This seems like a good way:

l1 = {a, {b, c}};
l2 = {d, {e, f}};
l3 = {g, {h, i}};

(* Out: {a, d, g, {b, c, e, f, h, i}} *)


It's been a few days, but I got distracted this morning from work and revisited this... My reward was seeing poetry (+1 btw), but I also killed a couple minutes running some timings on a sampling of the various answers:

ClearAll@t;
SetAttributes[t, HoldFirst];
t[e_, n_] := First@AbsoluteTiming[Do[e, {n}];]


OP:

t[
{Sequence @@ #1, Flatten[#2]} & @@ Transpose[{l1, l2, l3}],
10^6
]

(* Out: 3.849385 *)


t[
10^6
]

(* Out: 2.882288 *)


Snapshot of a few other answers:

t[
MapThread[Join, {l1, l2, l3}] /. Join -> Sequence,
10^6
]

(* Out: 5.532553 *)

t[
MapAt[Sequence @@ # &, Transpose[{l1, l2, l3}], {{1}, {2, All}}],
10^6
]

(* Out: 6.293629 *)

t[
FlattenAt[Flatten /@ Transpose[{l1, l2, l3}], 1],
10^6
]

(* Out: 3.969397*)


(Performance of this operation is probably irrelevant for the OP's purposes, but I always enjoy playing on the performance side of things.)

• Whats the -2 doing in this case? Commented Sep 26, 2014 at 10:30
• @GordonCoale ref/Apply, Details and Options: "A negative level -n consists of all parts of expr with depth n." See ref/Depth for more explanation. Commented Sep 26, 2014 at 14:41

I don't know if this is "smarter". Anyway:

ClearAll@k; SetAttributes[k, Listable];
k @@ {l1, l2, l3} /. k -> Sequence
(* {a, d, g, {b, e, h, c, f, i}} *)

• I think the output OP asking for is {a,d,g,{b,c,e,f,h,i}} (Why he accepted this 囧 ?) Commented Sep 27, 2014 at 4:44
♯ = {## & @@ #, ## & @@@ #2} & @@ ({##}) & ;

♯[l1, l2, l3]
(* {a, d, g, {b, c, e, f, h, i}} *)

• Look, Ma! No letters! +1. You could even replace m with \[FivePointedStar]. Commented Sep 26, 2014 at 17:51
• thank you @Michael; updated with something along those lines.
– kglr
Commented Sep 26, 2014 at 18:07
• This is evil. I approve. Commented Sep 26, 2014 at 21:52
• (1137) Commented Sep 26, 2014 at 22:02
• Yep, I can imagine in a near future #~♯~# == 42. @Mr.Wizard remember to give attribution. Commented Sep 27, 2014 at 5:20

My take:

MapAt[Sequence @@ # &, Transpose[{l1, l2, l3}], {{1}, {2, All}}]

{a, d, g, {b, c, e, f, h, i}}


This is another way:

FlattenAt[Flatten /@ Transpose[{l1, l2, l3}], 1]


{a, d, g, {b, c, e, f, h, i}}

One option:

l1 + l2 + l3 /. Plus -> Sequence


{a, d, g, {b, c, e, f, h, i}}

• @Mr.Wizard Tks!.. Now I have a nice one. Commented Sep 26, 2014 at 22:04
• Indeed you do. Probably not as general as would be best, but then again neither are several other answers, and the OP never really specified the problem. +1 Commented Sep 26, 2014 at 22:16
• Similar but more abusive: Re[l1, l2, l3] /. Re@x__ :> x Commented Sep 26, 2014 at 22:19
• This answer has the same spirit as belisarius's, so does the output: it outputs {a, d, g, {b, e, h, c, f, i}} rather than {a, d, g, {b, c, e, f, h, i}}. Commented Sep 27, 2014 at 4:50

Two very intuitive ways. First the Flattinator:

#2[#1[#1 /@ #1[{##3}, {2}], {1}], 1] &[Flatten, FlattenAt, l1, l2, l3]


PadLeft[{Flatten[#2]}, 4, RotateLeft[#1]] & @@ Transpose[{l1, l2, l3}]


• +1 But can't help frowning while shaking my head :) Commented Sep 26, 2014 at 15:01

Rule based alternatives for completeness sake:

{l1, l2, l3} //. {{a__, {b__}}, {c_, {d__}},
rest : {_, {__}} ...} :> {{a, c, {b, d}}, rest} // First


{a, d, g, {b, c, e, f, h, i}}

And:

Flatten[{l1, l2, l3}, {2, 1}] /. {start__, rest : {_, _} ...} :> {start, Join[rest]}


{a, d, g, {b, c, e, f, h, i}}

• Ha! I was tempted too :) Commented Sep 25, 2014 at 23:03

Another solution :

Join[#[[1]], {#[[2]]}] &@(Flatten /@ Transpose@{l1, l2, l3})
(* {a, d, g, {b, c, e, f, h, i}} *)


Update

Transpose @ {l1, l2, l3} /. a:{__Symbol} :> Sequence @@ a


{a, d, g, {b, c, e, f, h, i}}

Append[First /@ #, Flatten[Last /@ #]] & [{l1, l2, l3}]


{a, d, g, {b, c, e, f, h, i}}

• The desired output is {a, d, g, {b, c, e, f, h, i}} :D Commented Sep 25, 2014 at 23:02

I would just add something for general case:

l1 = {a, h, u, {b, t, c}};
l2 = {d, e, t, y, {e, f}};
l3 = {g, {h, i}};

Append @@ ({Cases[#, _?(Head[#] =!= List &)],
Flatten[Cases[#, _List]]} &[Flatten[{l1, l2, l3}, 1]])

(*{a, h, u, d, e, t, y, g, {b, t, c, e, f, h, i}}*)