# Riffle but not quite

Given the two lists below, is there an in-built command or otherwise neat way of accomplishing the desired output.

list = {{1, 2}, {5, 2}, {9, 3}, {6, 5}};
x = {x1, x2, x3, x4, x5, x6, x7};
desiredOutput = {{1, 2, x1}, {5, 2, x2}, {9, 3, x3}, {6, 5, x4}};


My attempt seems ugly:

{list[[#]][[1]], list[[#]][[2]], x[[#]]} & /@ (list // Length // Range)

• closely related: 51407
– Kuba
Jun 21, 2016 at 11:00
• Also related: (189), (13748), (14494) Jun 21, 2016 at 11:09

Example

Code

list = {{1, 2}, {5, 2}, {9, 3}, {6, 5}};
x = {x1, x2, x3, x4, x5, x6, x7};

MapThread[Append, {list, x[[;; Length  @ list]]}]


Output

{{1, 2, x1}, {5, 2, x2}, {9, 3, x3}, {6, 5, x4}}

Reference

• Why does MapThread[Append, {list, x[[;; Length @ list]]}] work but not MapThread[Append, {list, x[[;; list // Length]]}] work? Even though list // Length and Length@list give the same result?
– Tom
Jun 21, 2016 at 11:10
• @Tom consider ;; list // Length and ;; (list // Length).
– Kuba
Jun 21, 2016 at 11:13
• Oh ok, I suppose it's my lack of understanding of the order in which Mathematica computes things which tripped me up.
– Tom
Jun 21, 2016 at 11:15

There are so many ways to handle a problem like this and which one is preferred with depend on style, performance, the type and shape of your data, ease of recollection, etc., but here are several more:

Join[list, x ~Take~ Length[list] ~Partition~ 1, 2]

Riffle[Flatten @ list, x, {3, -1, 3}] ~Partition~ 3

PadRight[list, {Automatic, 3}, List /@ x]


And one inspired by J.M.'s use of Flatten

{list, x} ~Flatten~ {2} // Cases[{{x__}, y_} :> {x, y}]

• Yes, that is making nice use of Riffle right there. Good when one can read the documentation. :)
– gwr
Jun 21, 2016 at 11:25
• @gwr Thank you! Jun 21, 2016 at 11:30

Shortest so far:

i = 1; list /. {a_, b_} :> {a, b, x[[i++]]}

• +1, but after you add a Module to correctly localize i it will be longer than PadRight. :^) Jun 21, 2016 at 11:29
Transpose[Join[Transpose[list], {Take[x, Length[list]]}]]


should be quite fast for long lists. On my work desktop,

rand = RandomInteger[{1, 10}, {10^5, 2}];
xar = Array[x, 10^6];
AT = AbsoluteTiming;

AT[l1 = Transpose[Join[Transpose[rand], {Take[xar, Length[rand]]}]];]
(* {0.032721, Null} *)

AT[l2 = MapThread[Append, {rand, xar[[;; Length@rand]]}];]
(* {0.112556, Null} *)

AT[l3 = Table[{rand[[k, 1]], rand[[k, 2]], xar[[k]]}, {k, 1,
Length[rand]}];]
(* {1.975830, Null} *)

l1 == l2 == l3
(* True *)


EDIT: Some more timings just for fun, in no particular order :)

AT[l4 = (i = 1; rand /. {a_, b_} :> {a, b, xar[[i++]]});]
(* {0.161642, Null} *)

AT[l5 = ArrayFlatten[{{rand, {#} & /@ xar[[1 ;; Length[rand]]]}}];]
(* {0.186327, Null} *)

AT[l6 = Append @@@
DeleteCases[Flatten[{rand, xar}, {{2}, {1}}], {_}];]
(* {1.054091, Null} *)

AT[l7 = MapIndexed[Join[#1, xar[[#2]]] &, rand];]
(* {0.277814, Null} *)

AT[l8 = Join[rand, xar~Take~Length[rand]~Partition~1, 2];]
(* {0.083558, Null} *)

AT[l9 = Riffle[Flatten@rand, xar, {3, -1, 3}]~Partition~3;]
(* {0.028951, Null} *)

AT[l10 = PadRight[rand, {Automatic, 3}, List /@ xar];]
(* {0.315211, Null} *)


Table[{list[[k, 1]], list[[k, 2]], x[[k]]}, {k, 1, Length[list]}]


Using MapIndexed...

MapIndexed[Join[#1, x[[#2]]] &, list]


Yet another possibility, using Flatten[] as a "generalized Transpose[]":

Append @@@ DeleteCases[Flatten[{list, x}, {{2}, {1}}], {_}]
{{1, 2, x1}, {5, 2, x2}, {9, 3, x3}, {6, 5, x4}}

• Shorter: Append @@@ Cases[Flatten[{list, x}, {2}], {_, _}] (and +1) Jun 21, 2016 at 14:38
• Yes, that's more compact, @Mr. Wizard. Nevertheless, I still feel the need to remind myself of what Flatten[] is doing by specifying all levels explicitly in the second argument. But that's just my crutch... Jun 21, 2016 at 14:43
• A perfectly valid crutch, IMHO. Jun 21, 2016 at 14:44
list = {{1, 2}, {5, 2}, {9, 3}, {6, 5}};
x = {x1, x2, x3, x4, x5, x6, x7};
ArrayFlatten[{{list, {#} & /@ x[[1 ;; 4]]}}]

{{1, 2, x1}, {5, 2, x2}, {9, 3, x3}, {6, 5, x4}}


I haven't seen this yet, but it may be degenerate with someone else's answer.

Append @@@ Partition[Riffle[list, x], 2]


ArrayFlatten[{{list, Transpose[{x[[;; Length@list]]}]}}]

See here for some interesting comparisons by Timo

I think the preferred way to append columns X to matrix A is probably:

Join[X, A, 2]


Adding a single column is slightly less tidy

Join[list, Transpose[{x}], 2]