# List creation/manipulation

I'd like to a create a list from A = {{a}, {b}, {c}} by taking each elements n times in the following form:

B={{a},{a},{a},{b},{b},{b},{c},{c},{c}}


Any idea?

ConstantArray is your friend.

Flatten[ConstantArray[#, 3] & /@ {{a}, {b}, {c}}, 1]

{{a}, {a}, {a}, {b}, {b}, {b}, {c}, {c}, {c}}


Here is an interesting approach:

We first define a helper function:

f[x_] := Sequence[x, x, x]


Then it's just a matter of mapping it on A to create B:

A = {{a}, {b}, {c}};

f /@ A


{{a}, {a}, {a}, {b}, {b}, {b}, {c}, {c}, {c}}

We could also use a SubValues (or "operator form") definition for flexible replication:

g[n_][x_] := Sequence @@ ConstantArray[x, n];

g[3] /@ A


{{a}, {a}, {a}, {b}, {b}, {b}, {c}, {c}, {c}}

MapAt[g[3], A, 2]


{{a}, {b}, {b}, {b}, {c}}

• Nice idea. I added an extension assuming you wouldn't mind. Commented Aug 7, 2014 at 18:15
• @Mr.Wizard. I don't mind your edits at all. Nice addition by the way. Thanks. Commented Aug 7, 2014 at 18:17
• Unfortunately this method proves to be one of the slower ones. See my updated answer. (The colors are hard to distinguish but f9 is the line third from the top, meaning third slowest.) Commented Aug 7, 2014 at 18:52
• @Mr.Wizard. Oh well, we can't win all the time :) Commented Aug 7, 2014 at 18:54

My additions, duplicating the entire array first:

ConstantArray[A, 3] ~Flatten~ {2, 1}

Join @@ (ConstantArray[A, 3]\[Transpose])

Join @@ Thread @ ConstantArray[A, 3]



## Benchmarks

Timings for all methods in the order they were posted, tested only for triplication on a packed array.

f1[array_] :=
Composition[Flatten[#, 1] &, Replace[#, x_ :> ConstantArray[x, 3], 1] &][array]
f2[A_] := Flatten[ConstantArray[#, 3] & /@ A, 1]
f3[A_] := Flatten[A /. {x_} :> {{x}, {x}, {x}}, 1]
f4[A_] := Flatten[{#, #, #} & /@ A, 1]
f5[A_] := ConstantArray[A, 3] ~Flatten~ {2, 1}
f6[A_] := Join @@ (ConstantArray[A, 3]\[Transpose])
f7[A_] := Join @@ Thread @ ConstantArray[A, 3]
f8[A_] := Sequence ~MapThread~ ConstantArray[A, 3]
f[x_] := Sequence[x, x, x];
f9[A_] := f /@ A

gen = RandomInteger[99, {#, 1}] &;

Needs["GeneralUtilities"]

BenchmarkPlot[
{f1, f2, f3, f4, f5, f6, f7, f8, f9},
gen, 2^Range[20], "IncludeFits" -> True
]


All methods have the same order of complexity but there is a clear winner for speed:

f5[A_] := ConstantArray[A, 3] ~Flatten~ {2, 1}


Running the tests again with unpackable data:

gen2 = "a" ~CharacterRange~ "z" ~RandomChoice~ {#, 1} &;

BenchmarkPlot[
{f1, f2, f3, f4, f5, f6, f7, f8, f9},
gen2, 2^Range[20], "IncludeFits" -> True
]


The winners are f6, f7, and f5 in order, with f6 and f7 only slightly ahead of f5 which does not justify their use given f5's large margin of performance on packed data.

• +1 for Flatten. BTW my MMA 10 could not generate BenchmarkPlot. All I got was this. Commented Aug 7, 2014 at 19:20
• @seismatica Thanks for the vote. Very strange error; I guess BenchmarkPlot has some bugs to work out. The package is very new and rough in spots. Commented Aug 7, 2014 at 19:32
• Is this a built-in package or do I have to download it somewhere? Commented Aug 7, 2014 at 19:32
• @seismatica It is built into version 10 and should be loaded by the line Needs["GeneralUtilities"] Commented Aug 7, 2014 at 19:39

Just for variation, using replacement rules we have for small n:

Flatten[{{a}, {b}, {c}} /. {x_} :> {{x},{x},{x}}, 1]


and for large n :

Flatten[{{a}, {b}, {c}} /. {x_} :> Table[{x}, {3}], 1]

• For large n, Table will slow down a bit. Commented Aug 7, 2014 at 13:43

Use Replace with levelspec = 1

createArray[array_, n_] := Composition[
Flatten[#, 1] &,
Replace[#, x_ :> ConstantArray[x, n], 1] &
][array]


Check function:

createArray[{{a},{b},{c}}, 3]
(*{{a},{a},{a},{b},{b},{b},{c},{c},{c}}*)


Different approaches (just for fun)

Join @@ (ComposeList[Table[# &, {2}], #] & /@ A)
Join @@ (Nest[Append[#, First@#] &, {#}, 2] & /@ A)
Join @@ (NestList[# &, #, 2] & /@ A)
Fold[Riffle[#1, A, {#2, -1, #2}] &, A, {2, 3}]

Flatten[PadLeft[{#}, 3, {#}] & /@ {{a}, {b}, {c}}, 1]