2017-11-17 23 views
0

私はD = {2: 4, 3: 2, 5: 1, 7: 1}という形の単純な辞書を持っています。素数である4つのキーと最大のパワーを表す4つの値があります。Pythonで複数の入れ子になったループを置き換える

P1 ^範囲1の* P2 ^範囲2の* P3を^レンジ3 * P4^range4

range1range4に対応する範囲です:私は、フォームのすべての組み合わせを生成することに基づいて、各素数の辞書の値。 p1 = 2の場合、範囲は次のようになりますrange(0, 4+1)最も単純な方法は、4つのレベルでループのために入れ子にされるだろう

:私が意図するものであり、それは正しいですが、これは非エレガントかつ機械的である

for i1 in range(0, 4+1): 
    for i2 in range(0, 2+1): 
     for i3 in range(0, 1+1): 
     for i4 in range(0, 1+1): 
      n = 2**i1 * 3**i2 * 5**i3 * 7**i4 

方法。

もう1つの方法は、すべての範囲が同じ場合に機能するitertools.productを使用することです。基本的には以下の通りである:

for x in itertools.product(range(0, 4+1), repeat=4): 
    print(x, end=' ') 

しかしこれを含むすべての可能な組み合わせを生成する(2、2、3、4)、 (4、4、2、3)又は(2、3、4、私の場合、5の冪(タプルの3番目の要素)が3になることはなく、7の累乗は決して4にはならないと私の場合は正しくありません。従って、この場合、最大タプルは、パワー(辞書Dの値)に対応する(4,2,1,1)となる。ですから、基本的には(0,0,0,0)から(4,2,1,1)までのタプルの範囲しか必要としません。

forループを使用せずにこれを実現する方法は、itertools.productと同様の方法で行いますか?

事前に感謝します。解決策を書いた

miraduloとして実際に

+3

ものは等価ではありません。 'itertools.product(range(5)、range(3)、range(2)、range(2))'または 'itertools.product(* map(range、(5,3,2,2)) ) '。 – miradulo

+0

ありがとうございました。それはまさに私が欲しいものです。これは私の問題を解決します。 – youth4ever

答えて

1

は、非常に簡単です: 次のいずれかを使用します

for x in itertools.product(*map(range, (5, 3, 2, 2))) : 
    print(x, end=' ') 

か:

for x in itertools.product(range(5), range(3), range(2), range(2)) : 
    print(x, end=' ') 

どちらの方法で問題を解決します。

1

itertoolsが移動するための方法ですが、この質問は、発電機の機能を実施するための優れた運動です:

def multirange(d): 
    if len(d) == 1: 
     for i in range(d[0]): 
      yield [i] 
    elif len(d) > 1: 
     for i in range(d[-1]): 
      for a in multirange(d[:-1]): 
       yield a + [i] 

def multirange_b(d): 
    l = len(d) 
    products = [1] 
    for k in d: 
     products.append(products[-1]*k) 
    n = products[-1] 
    for i in range(n): 
     yield [(i%products[j+1])//products[j] for j in range(l)] 

for l in multirange([4,3,2]): 
    print(l) 

for l in multirange_b([4,3,2]): 
    print(l) 
関連する問題