Reputation: 11
NOTE: corrected question!
It is well-known that itertools
allows for easy creation of nested for
loops using itertools.product
. But the following is what I want and can't do yet. Using
lfl = int(input( "length of first loop: "))
nol = int(input( "number of loops: "))
Causing:
I want an equivalent to:
for i1 in range(1,12):
for i2 in range(i1,12):
for i3 in range(i2,12):
for i4 in range(i3,12):
function(i1,i2,i3,i4)
itertools.product
does way to many.
Or the more general question where nol
causes the creating of func_1(x), func_2(x,y), .... func_nol-1(x,y,...) and the code needs to be equivalent to:
for i1 in range(1,12):
for i2 in range(func_1(i1),12):
for i3 in range(func_2(i1,i2),12):
for i4 in range(func_3(i1,i2,i3),12):
function(i1,i2,i3,i4)
And one more further generalization would be
for i1 in range(1,12):
for i2 in range(start_func_1(i1, *global),end_func_(12, *global)):
for i3 in range(start_func_2(i1,i2,*global),end_func_2(12,*global):
for i4 in range(start_func_3 etc....
Upvotes: 1
Views: 111
Reputation: 10784
For your corrected question, try combinations_with_replacement
instead of product
on your list of ranges:
from itertools import combinations_with_replacement
nums = [10, 11, 12, 13]
for c in combinations_with_replacement(nums, 3):
print c
prints
(10, 10, 10)
(10, 10, 11)
(10, 10, 12)
(10, 10, 13)
(10, 11, 11)
(10, 11, 12)
(10, 11, 13)
(10, 12, 12)
...
Upvotes: 1
Reputation: 32580
This is exactly equivalent to the code you provided:
from itertools import product
lfl = 12
nol = 4
ranges = (range(i, lfl) for i in range(1, nol + 1))
args = product(*ranges)
for arg in args:
function(*arg)
It uses a generator expression to build the list of ranges used for the loops to pass to itertools.product
and argument list unpacking to pass a single tuple of arguments as separate arguments to the function / to product()
.
Demonstration:
from itertools import product
def function(*args):
return args
results_nested = []
results_product = []
for i1 in range(1, 12):
for i2 in range(2, 12):
for i3 in range(3, 12):
for i4 in range(4, 12):
results_nested.append(function(i1, i2, i3, i4))
lfl = 12
nol = 4
ranges = (range(i, lfl) for i in range(1, nol + 1))
args = product(*ranges)
for arg in args:
results_product.append(function(*arg))
assert results_nested == results_product
Upvotes: 0
Reputation: 42597
You can do this using product
- you just need to create the 'dimensions' of the loops in an initial preparation step:
from itertools import product
length = 12
loops = 4
ranges = [range(x+1,length) for x in range(loops)]
def f(x): # accepts a tuple, since the number of arguments may vary
print("f(%s)" % repr(x))
for t in product(*ranges):
f(t)
Upvotes: 0