# Creating a list from other lists and varying the number of elements that get added

Suppose I have

 listA = {M, F}


and

ListB = {a,b,c}


I want to make a new

listC = {{Ma, Mb, Mb, Mb, Mc, Mc}, {Fa, Fb, Fb, Fb, Fc, Fc}}


Where I tell Mathematica how many copies of a particular element to make in listC.

Outer[] seems like a good start but it returns the combined elements as a two item list. For example I get {M, a} instead of M a.

-
Do you mean M * a or a new symbol called Ma ? – b.gatessucks Mar 30 '13 at 20:03
"Where I tell Mathematica how many copies of a particular element to make in listC" in what format do you want to supply this information? – acl Mar 30 '13 at 20:10
Outer seems like the answer, it combines, and wraps a combination of elements with a specified function, if the function is Times, you can get get a M, if it's List, you get {M, a} instead. – BoLe Mar 30 '13 at 20:28
I edited your question trying to make it easier to read. Next time please try to do it yourself. – Dr. belisarius Mar 30 '13 at 20:40
@belisarius Thanks for the editing. I am new to the site so I am still trying sort out how things work. I will do that next time. – spaceKnot Mar 30 '13 at 20:59

I just noticed your comment under the question that you actually do want new symbols. I shall give an example of that and also multiplication.

It is more efficient to perform the operation (multiplication, etc.) and then make the copies, rather than making copies and performing the operation anew on each.

f[A_, B_, R_, f_: Times] := Inner[ConstantArray, Outer[f, A, B], R, Join]

f[{M, F}, {a, b, c}, {1, 3, 2}

{{a M, b M, b M, b M, c M, c M}, {a F, b F, b F, b F, c F, c F}}


Symbols:

makeSym = Symbol @ ToString @ Row @ {##} &;

f[{M, F}, {a, b, c}, {1, 3, 2}, makeSym]

{{Ma, Mb, Mb, Mb, Mc, Mc}, {Fa, Fb, Fb, Fb, Fc, Fc}}


With argument checking for practical use:

f[A_List, B_List, R : {__Integer}, f_: Times] /;
Min[R] >= 0 && Length@B == Length@R :=
Inner[ConstantArray, Outer[f, A, B], R, Join]

-
Thank you! Very simple to follow the code. However I am not sure I get how makeSym fits in the picture. Is it replacing f_:Times which is the 4th argument when f[A_, B_, R_, f_: Times] gets defined. If that is true, then makeSym is being passed into Outer as the first argument which makes the return value a string? – spaceKnot Apr 2 '13 at 17:43
@spaceKnot You're welcome. I see that there is an error in my code which I will now correct. (I forgot to update the right-hand-side when I updated the left.) The Pattern: f_: Times defines an Optional parameter with a default values of Times. If no fourth argument is given Times is used where f appears; if an argument is given it instead is used. Sorry for the mistake, and if anything isn't clear please ask again. – Mr.Wizard Apr 2 '13 at 23:11
Thank you again! That clarified my question :) – spaceKnot Apr 4 '13 at 7:03
@spaceKnot Are you aware that you can Accept one answer that you find fully satisfactory (and you can change the Accept at a later time)? You are not required to do so but it is appreciated. – Mr.Wizard Apr 4 '13 at 23:52
@Mr.Wiazrd Sorry, still learning the rules. – spaceKnot Apr 5 '13 at 0:17

Assuming Ma is the product M * a, you could state the number of copies:

copies = {1, 3, 2};


Then make these copies:

listD = Flatten[Inner[Table[#1, {#2}] &, listB, copies, List]]


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

And finally combine them with the first list:

Outer[Times, listA, listD]


{{a M, b M, b M, b M, c M, c M}, {a F, b F, b F, b F, c F, c F}}

Update

If you really want a new symbol Ma, you could perhaps do this with strings.

listA = {"M", "F"};
listB = {"a", "b", "c"};
copies = {1, 3, 2};
listD = Flatten[Inner[Table[#1, {#2}] &, listB, copies, List]];
Outer[ToExpression[#1 <> #2] &, listA, listD]


{{Ma, Mb, Mb, Mb, Mc, Mc}, {Fa, Fb, Fb, Fb, Fc, Fc}}

-
Thank you BoLe! – spaceKnot Mar 30 '13 at 21:17
@spaceKnot Very flexible, this Outer. – BoLe Mar 30 '13 at 21:31