2016-06-28 7 views
-1

動的なforループを作成するには、再帰的またはitertoolsモジュールをPythonで作成する方法があります。私は再帰的にそれをやっていると言うことができます。私は2つのリスト動的Forループin Python

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) 

nは変数

の数である私がしたいことはnの

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

繰り返しループされて私が今持っているを持っている私は、リセットをしましたそれは範囲外になるlist_indexで、私は私が望む結果を得ることができませんでした。誰かが間違ったことを教えてもらえますか?

+1

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,))) 

今、私たちはそうのようにそれを使用することができます。あなたは正確に何を達成しようとしていますか? – 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(b[0], b[1], b[2])のように別々の引数としてrange()に適用されます。

同じことがproduct()コールに適用されます。ジェネレータ式が生成する各range()オブジェクトは、別の引数としてproduct()に渡されます。この方法で、range()オブジェクトの動的番号をその呼び出しに渡すことができます。

+0

あなたは製品に渡されたジェネレータ、つまりスプラットを解凍する必要があると思います! –

+0

@ juanpa.arrivillaga:ああ、はい、もちろんです。 –

+0

ありがとう!私はまだPythonには新しかったので、あなたが書いたその1つのライナーをまだ消化しています – Max

0

ちょうど楽しみのために、私はおそらくpythonスタイルを示すために再帰を使用してこれを実装すると考えました。もちろん pythonic wayは、Martijn Pietersのデモンストレーションのようにitertoolsパッケージを使用することです。これは、過エンジニアリング明らかである

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