2017-02-21 11 views
5

Ok。Python:範囲内の値のn長配列の組み合わせを生成する

[0,0,0] 
[0,0,1] 
[0,0,2] 
... 
[1,0,0] 
[1,0,1] 
... 

など:私はこのような値、B、Cのためのすべての組み合わせを生成する必要がありますされ、この関数に

def f(): 
    [[a,b,c] for a in range(6) for b in range(6) for c in range(6)] 

を行うには賢い、よりコンパクトな方法を探しています。 ..

しかし、私はこれを柔軟にしたいので、範囲や反復可能性、そして生成された配列の長さを変更できます。範囲は簡単なことである:

def f(min, max): 
    [[a,b,c] for a in range(min,max) for b in range(min,max) for c in range(min,max)] 

これは3長配列のためにOKですが、私は4長配列または7長配列を作ることを今考えと同じ範囲内のそれらのためのすべての組み合わせを生成しています。

配列を連結したり、何らかの形で入れ子リストを入れたりするのは簡単な方法ですが、私のソリューションは複雑すぎるようです。

このような長い投稿には申し訳ありません。

+2

'itertools'モジュールは、正確に何をして' product'機能を持っています探しています。 'itertoolsからインポート製品。製品(範囲(6)、範囲(6)、範囲(6)) 'を含む。どのイテレーターが最後に置かれても、最も早くサイクルします。 – Elliot

答えて

3

itertools.productは、ネストされた繰り返しの便利な機能です。

>>> from itertools import product 

>>> amin = 0 
>>> amax = 2 
>>> list(product(range(amin, amax), repeat=3)) 
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] 

あなたがmapを使用することができlistlistを取得するには:

>>> list(map(list, product(range(amin, amax), repeat=3))) 
[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]] 

それはですので、しかしproductがイテレータであるそれはまた、あなたが同じiterableを複数回繰り返したい場合はrepeat -argumentを持っていますlistにキャストするのではなく、繰り返し処理すれば効率的です少なくともあなたのプログラムでそれが可能ならば。例:

>>> for prod in product(range(amin, amax), repeat=3): 
...  print(prod) # one example 
(0, 0, 0) 
(0, 0, 1) 
(0, 1, 0) 
(0, 1, 1) 
(1, 0, 0) 
(1, 0, 1) 
(1, 1, 0) 
(1, 1, 1) 
+0

私は最終的に '[elem in product(* repeat(iterable、times)] ')のリストを使って1行を作った。 – madtyn

1

itertoolsには必要なものがすべて含まれています。 combine_with_replacementは、指定された長さと指定された反復可能要素からの反復要素の組み合わせを生成します。戻り値はイテレーターになります。

def f(min, max, num):  
    return itertools.combinations_with_replacement(range(min, max), num) 
+0

他の状況ではいいですが、[0,0,1]!= [1,0,0]が必要でした。順序は重要です。たぶん、私はよりよく説明していたはずです。私はこれを書き留めますが、 – madtyn

+0

のように、他の回答が記載されているように - itertools.productが良いでしょう。 – Pearley

6

あなたはitertools.productを使用することができます。

from itertools import product 

def f(mn, mx, n): 
    return list(product(*[range(mn, mx)]*n))) 

ドロップlist、メモリ効率のための発電機を返却します。

-1

あなたが探しているのは、範囲のデカルト積です。幸いにもこれは既にitertoolsに存在

import itertools 
print(list(itertools.product(range(0,5), range(0,5), range(0,5)))) 
1

純粋なPython実装:

k=2 # k-uples 
xmin=2 
xmax=5 
n=xmax-xmin 

l1 = [x for x in range(n**k)] 
l2 = [[ x//n**(k-j-1)%n for x in l1] for j in range(k)]   
l3 = [[ xmin + l2[i][j] for i in range(k)] for j in range(n**k)] 

l3は次のとおりです。

[[2 2] 
[2 3] 
[2 4] 
[3 2] 
[3 3] 
[3 4] 
[4 2] 
[4 3] 
[4 4]] 
+0

コードを見直すべきだ。 * //構文エラーを返します – madtyn

+0

'//'です。それは正常に動作します – madtyn

+0

"純粋なビルトイン"実装というよりむしろ。私はPythonの標準ライブラリの機能を使った場合よりも、読み込み不能で、おそらくメモリと時間のオーバーヘッドが増えるため、Pythonでないことがわかります。 – Pearley

関連する問題