# Do with variables from a table

I want to perform a Do command with n variables, where n is set elsewhere in my code. How do I do that?

For example, suppose s={0,1} and n=2, then I want a code that runs

Do[Print[{var1,var2}],{var1,s},{var2,s}]


and when I set n=3, then I want a code that runs

Do[Print[{var1,var2,var3}],{var1,s},{var2,s},{var3,s}].


(Print is used just as a simple example here.) I have tried

Do[Print[ToExpression[Table["i"<>ToString[i],{i, n}]]],ToExpression[Table["{i"<>ToString[i]<>",s}",{i, 1, n}]]]


but Mathematica complains due to the result of the second ToExpression containing extra pair of curly brackets (Table produces a list). I tried removing these brackets with Row (as suggested https://community.wolfram.com/groups/-/m/t/1219718) or Delete (as suggested here Is there a function in Mathematica which removes brackets wrapping an expression?), but could not get code to work due to my limited knowledge of Mathematica.

I know I can do Tuples but that produces a large output when s is large (i.e., requires a lot of memory).

• Can you explain in more detail what you are trying to achieve in the end? Here's an easy way to compute an arbitrary dimensional array where the elements are the sums of indices. Array[Total[{##}] &, {3, 4, 2}] Notice that it generalizes to $n$ dimensions without problem. Can you explain your use case in enough detail that it becomes apparent why such a solution would not be possible for you? May 11 '20 at 10:56
• @Szabolcs: Apologies for the missing context. I am trying to generate all n dimensional vectors such that a) all elements are drawn from s, b) the elements sum to 1 and c) the elements are increasing. One way to do this is to generate all n tuples from s and then test each tuple for a)-c). However, this generates all tuples at ones and requires a lot of memory when s is large.
– Jan
May 11 '20 at 11:04
• Since the elements must be increasing, I would use Subsets, not Tuples. This will improve performance significantly because you just got rid of a lot of permutations. If there are still too many subsets, you can use Subsets's 3rd argument to only generate the nth one, thus being able to iterate through them without generating all of them first. May 11 '20 at 11:39
• @Szabolcs: Thank you. Let me confirm that using Subsets works as suggested. Thank you.
– Jan
May 11 '20 at 12:00

If you want to loop over what would be the result of Tuples[s, {n}] without generating all tuples at once, then you need to recall that tuple generation is isomorphic to generating $$n$$-digit base-$$b$$ numbers, where b == Length[s]:

n = 3; s = {0, 1};
b = Length[s];
Do[Print[s[[IntegerDigits[k, b, n] + 1]]], {k, 0, b^n - 1}]


Otherwise, there is the option of programatically generating the iterators:

Do[Print[Array[K, n]], ##] & @@ ({#, s} & /@ Array[K, n])


Here, I use K[n] as the loop variable for each level.

• There are 3 suggested ways to do what I originally asked: Subsets, $n$-digit base-$b$ and Array. All three work as intended. The $n$-digit base-$b$ seems to be the fastest.
– Jan
May 11 '20 at 12:02