2
$\begingroup$

I have two lists:

list1={4,6}
list2={1,2}

and I now want a function f that produces

f[list1_,list2_]:={1,1,1,1,2,2,2,2,2,2}

so 4 times the 1 and 6 times the 2. f should be generic so that

3list1={2,3,7}; 3list2={1,2,3}

yields

res={1,1,2,2,2,3,3,3,3,3,3,3}

If you know several ways to do this please provide the fastest one. thanks a lot.

$\endgroup$
  • $\begingroup$ Table[list2[[#]], {list1[[#]]}] & /@ Range@Length@list1 // Flatten $\endgroup$ – eldo Jun 3 '14 at 18:16
  • $\begingroup$ Flatten @ MapThread[ ConstantArray[ #2 , #1 ] &, { list1 , list2 } ] $\endgroup$ – mfvonh Jun 3 '14 at 18:20
  • $\begingroup$ Flatten@MapThread[ConstantArray[##] &, {list2, list1}] $\endgroup$ – eldo Jun 3 '14 at 18:24
  • $\begingroup$ Related: (40724) and related Stack Overflow question: (763915) $\endgroup$ – Mr.Wizard Jun 3 '14 at 21:19
  • $\begingroup$ @Mr.Wizard - related or not - how would you write this ? $\endgroup$ – eldo Jun 3 '14 at 22:30
4
$\begingroup$
f[list1_, list2_] := Inner[Table[#2, {#1}] &, list1, list2, Join];
$\endgroup$
  • $\begingroup$ this is very clear and understandable, thanks. $\endgroup$ – spore234 Jun 3 '14 at 19:06
3
$\begingroup$
list1 = {4, 6}
list2 = {1, 2}

ClearAll[f];
f = Join @@ MapThread[Table, {#2, List /@ #1}] &

f[list1, list2]
(* {1, 1, 1, 1, 2, 2, 2, 2, 2, 2} *)

f[{2, 3, 7}, {1, 2, 3}]
(* {1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3} *)

or

h = Join @@ (Table @@@ Transpose[{#2, List /@ #1}]) &
h[{2, 3, 7}, {1, 2, 3}]
(* {1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3} *)

or

g = Join @@ (ConstantArray @@@ Transpose[{#2, #1}])&

g2 = Inner[ConstantArray, #2, #1, Join] &

Timings:

bh = Inner[Table[#2, {#1}] &, #1, #2, Join] &; (* BobHanlon *)

{listA, listB} = RandomInteger[100, {2, 100000}];
(rs1 = bh[listA, listB]); // Timing
(* {0.265625, Null} *)
(rs2 = g[listA, listB]); // Timing
(* {0.062500, Null} *)
(rs3 = g2[listA, listB]); // Timing
(* {0.078125, Null} *)
(rs4 = h[listA, listB]); // Timing
(* {0.296875, Null} *)
(rs5 = f[listA, listB]); // Timing
(* {0.296875, Null} *)
rs1 == rs2 == rs3 == rs4 == rs5
(* True *)
$\endgroup$
  • $\begingroup$ your solution is the fastest so far. $\endgroup$ – eldo Jun 3 '14 at 18:37
  • $\begingroup$ @eldo As usual I'm the slowest so far :) $\endgroup$ – mfvonh Jun 3 '14 at 18:46
  • 1
    $\begingroup$ With two 10^6 - Integer-Lists, MM 9.01 and 4 cores: Bob Hanlon -> 1.34, kguler -> 1.53, mfvonh -> 2.07, eldo -> 3.15 (up to 3 repetitions). $\endgroup$ – eldo Jun 3 '14 at 18:58
  • $\begingroup$ @kguler - why is "g" so much faster than "f" given the fact that both are kguler-offsprings :) $\endgroup$ – eldo Jun 3 '14 at 19:31
  • 1
    $\begingroup$ @eldo, it is because i could not get g working properly first time I tried and f worked right away :) I cannot locate the source on this site right now, but Join@@.. is usually faster than Flatten and ConstantArray is also faster than alternatives like Table and Array. $\endgroup$ – kglr Jun 3 '14 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.