2016-06-28 108 views
-1

我明白,要创建动态for循环,python中的递归或itertools模块是要走的路。可以说我正在递归的。动态Python中的循环

我要的是

for var1 in range(var1_lowerlimit, var1_upperlimit, var1_stepsize): 
    for var2 in range(var2_lowerlimit, var2_upperlimit, var2_stepsize): 
    : 
    : 
     # do_whatever() 

重复了N个回路,其中n为变量

我现在是多少我有2所列出

variable_list = [ var1, var2, var3, ... ] 
boundaries_list = [ [var1_lowerlimit, var1_upperlimit, var1_stepsize], 
        [var2_lowerlimit, var2_upperlimit, var2_stepsize], ...] 

def dynamic_for_loop(variable_list , boundaries_list, no_of_loops, list_index = 0): 
    if no_of_loops <= 0: 
     # do_whatever() 
    else: 
     lower_bound = boundaries_list[list_index][0] 
     upper_bound = boundaries_list[list_index][1] 
     step_size = boundaries_list[list_index][2] 
     for index in range(lower_bound, upper_bound, step_size): 
      list_index += 1 
      try: 
       dynamic_for_loop(variable_list , boundaries_list, no_of_loops - 1, list_index) 
      except: 
       list_index = 0 
       dynamic_for_loop(variable_list , boundaries_list, no_of_loops - 1, list_index) 

我做了复位在list_index上,因为它超出范围,但我无法得到我想要的结果。有人能够启发我出了什么问题吗?

+1

这显然是过度工程。你究竟想达到什么目的? – DeepSpace

+1

并且不要试图将其解压到单独的变量中。如果你的循环计数是可变的,那么只需处理元组'product()'就可以动态生成。 –

+0

它的一个组合研究通过改变一些变量,每个变量都有自己的边界来观察,这就是为什么我把变量和边界变成一个列表来访问它使用list_index – Max

回答

2

使用itertools.product()功能在范围内的变量数生成的值:

for values in product(*(range(*b) for b in boundaries_list)): 
    # do things with the values tuple, do_whatever(*values) perhaps 

不要尝试设置可变数量的变量;只需遍历values元组或根据需要使用索引。

在调用中使用*告诉Python获取迭代的所有元素并将它们作为单独的参数应用。因此,您的boundaries_list中的每个b作为单独的参数应用于range(),就像您调用range(b[0], b[1], b[2])一样。

这同样适用于product()调用;生成器表达式生成的每个range()对象作为单独的参数传递给product()。通过这种方式,您可以将动态号码range()传递给该呼叫。

+0

我相信你需要解开你传递给产品的发电机,也就是啪啪! –

+0

@ juanpa.arrivillaga:啊,是的,当然。 –

+0

谢谢!我对Python非常陌生,所以我仍然在消化你刚写的一行代码 – Max

0

只是为了好玩,我以为我会实现这个使用递归来展示pythonic风格。当然,如Martijn Pieters所证明的那样,pythonic的方式将使用itertools包。

def dynamic_for_loop(boundaries, *vargs): 
    if not boundaries: 
     print(*vargs) # or whatever you want to do with the values 
    else: 
     bounds = boundaries[0] 
     for i in range(*bounds): 
      dynamic_for_loop(boundaries[1:], *(vargs + (i,))) 

现在我们可以使用它像这样:

In [2]: boundaries = [[0,5,1], [0,3,1], [0,3,1]] 

In [3]: dynamic_for_loop(boundaries) 
0 0 0 
0 0 1 
0 0 2 
0 1 0 
0 1 1 
0 1 2 
0 2 0 
0 2 1 
0 2 2 
1 0 0 
1 0 1 
1 0 2 
1 1 0 
1 1 1 
1 1 2 
1 2 0 
1 2 1 
1 2 2 
2 0 0 
2 0 1 
2 0 2 
2 1 0 
2 1 1 
2 1 2 
2 2 0 
2 2 1 
2 2 2 
3 0 0 
3 0 1 
3 0 2 
3 1 0 
3 1 1 
3 1 2 
3 2 0 
3 2 1 
3 2 2 
4 0 0 
4 0 1 
4 0 2 
4 1 0 
4 1 1 
4 1 2 
4 2 0 
4 2 1 
4 2 2