I am trying to do some parameter testing on another code using python. I need to test 6 independent parameters, but I need all of the possible combinations of them.
Each parameter has a minimum, a maximum, and a step value that needs to be passed to it. The first easy solution that popped into my head was a nested for loop structure that looked horrific, like this:
for var1 in xrange(min1,max1,step1):
for var2 in xrange(min2,max2,step2):
...
...
...
for var6 in xrange(min6,max6,step6):
'''
Do something and be icky in the process due
to being in the middle of six nested for loops
'''
I decided, no! This shall not stand. So I’ve been trying to work out a way to do this recursively, or at the very least, not nested six times. I can’t really come up with a good scheme to do so. The biggest obstacle for me is that each variable has a different min, max, and step value.
My thoughts so far aren’t very helpful. I keep trying to make some recursive function work, but I just can’t figure it out without nesting more for loops within the function. I’ve seen a lot of reference to itertools.product on here, but I can’t quite figure out how to make that work either.
Edit: What I’m doing is creating a directory named after the combination of the parameters, writing a file with those parameters, running another code with this file, and analyzing the output from that code. I am doing nothing in literally any of the for loops except for the final one. A lot of the parameters only have 2 values, some have 10, others have 3… it just kind of varies.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Here’s how to use product:
x1 = xrange(min1,max1,step1)
x2 = xrange(min2,max2,step2)
x3 = xrange(min3,max3,step3)
...
for v1, v2, v3, v4, v5, v6 in itertools.product(x1, x2, x3, x4, x5, x6):
icky_thing(....)
or a bit more compactly:
ranges = [
xrange(min1,max1,step1),
xrange(min2,max2,step2),
xrange(min3,max3,step3),
...
]
for v1, v2, v3, v4, v5, v6 in itertools.product(*ranges):
icky_thing(....)
Method 2
You can probably use itertools.product: http://docs.python.org/library/itertools.html#itertools.product .
Something like
for var1, var2 in itertools.product(xrange(min1, max1, step1), xrange(min2, max2, step2)):
# stuff
. . . only with all six vars in there.
Method 3
you can use multiprocessing and itertools.product to speed up and simplify your code
import itertools
from multiprocessing import Pool
ranges = [
range(min1,max1,step1),
range(min2,max2,step2),
range(min3,max3,step3),
...
]
with Pool(os.cpu_count()-2) as p:
result = p.map(your_op_func, itertools.product(*ranges))
multiprocessingcan speed up your task (because it’s mutex task)itertools.productcan help you get combinations through a more effectively way
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0