web-dev-qa-db-ja.com

pythonでリストのすべての組み合わせを生成する

質問は次のとおりです。

Pythonのアイテムのリストが与えられた場合、アイテムの可能なすべての組み合わせを取得するにはどうすればよいですか?

このサイトには、itertools.combineの使用を推奨する同様の質問がいくつかありますが、必要なもののサブセットのみが返されます。

stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
    for subset in itertools.combinations(stuff, L):
        print(subset)

()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 3)
(1, 2, 3)

ご覧のとおり、(2、1)、(3、2)、(3、1)、(2、1、3)、(3、1、2)、( 2、3、1)、および(3、2、1)。回避策はありますか?何も思い付かないようです。

24
Minas Abovyan

つかいます - itertools.permutations

>>> import itertools
>>> stuff = [1, 2, 3]
>>> for L in range(0, len(stuff)+1):
        for subset in itertools.permutations(stuff, L):
                print(subset)
...         
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
....

itertools.permutations

permutations(iterable[, r]) --> permutations object

Return successive r-length permutations of elements in the iterable.

permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
>>> 
33

pythonこの単純なコードを使用して)のリストのすべての組み合わせを生成できます

import itertools

a = [1,2,3,4]
for i in xrange(1,len(a)+1):
   print list(itertools.combinations(a,i))

結果:

[(1,), (2,), (3,), (4,)]
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
[(1, 2, 3, 4)]
8

代わりに _itertools.permutations_ をお探しですか?

help(itertools.permutations)から、

_Help on class permutations in module itertools:

class permutations(__builtin__.object)
 |  permutations(iterable[, r]) --> permutations object
 |  
 |  Return successive r-length permutations of elements in the iterable.
 |  
 |  permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
_

サンプルコード:

_>>> from itertools import permutations
>>> stuff = [1, 2, 3]
>>> for i in range(0, len(stuff)+1):
        for subset in permutations(stuff, i):
               print(subset)


()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
_

ウィキペディアから、順列と組み合わせの違い:

順列:

非公式には、オブジェクトのセットの順列は、特定の順序へのオブジェクトの配置です。たとえば、セット{1,2,3}には6つの順列、つまり(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)があります。 、(3,1,2)、および(3,2,1)。

組み合わせ:

数学では、組み合わせとは、(順列とは異なり)順序が重要ではない大きなグループからいくつかのものを選択する方法です。

6
Sukrit Kalra

これはitertoolsを使用しないソリューションです

最初に、01sのインジケーターベクトルとサブリスト(アイテムがサブリストにある場合は1)間の変換を定義します。

def indicators2sublist(indicators,arr):
   return [item for item,indicator in Zip(arr,indicators) if int(indicator)==1]

次に、02^n-1の間の数値からそのバイナリベクトル表現へのマッピングを定義します(文字列のformat関数を使用):

def bin(n,sz):
   return ('{d:0'+str(sz)+'b}').format(d=n)

私たちがやるべきことは、可能なすべての数字を繰り返し、indicators2sublistを呼び出すことです。

def all_sublists(arr):
  sz=len(arr)
  for n in xrange(0,2**sz):
     b=bin(n,sz)
     yield indicators2sublist(b,arr)
2
Uri Goren

itertools.permutationsはあなたが望むものになるでしょう。数学的な定義では、combinationsの順序は重要ではありません。つまり、(1,2)(2,1)と同一と見なされます。一方、permutationsでは、個別の順序はそれぞれ一意の順列としてカウントされるため、(1,2)(2,1)は完全に異なります。

2
Brien

値の「セット」として可能なすべての組み合わせが必要だと思います。アイデアを提供するのに役立つかもしれない、私が書いたコードの一部を次に示します。

def getAllCombinations(object_list):
    uniq_objs = set(object_list)
    combinations = []
    for obj in uniq_objs:
        for i in range(0,len(combinations)):
            combinations.append(combinations[i].union([obj]))
        combinations.append(set([obj]))
return combinations

サンプルを次に示します。

combinations = getAllCombinations([20,10,30])
combinations.sort(key = lambda s: len(s))
print combinations
... [set([10]), set([20]), set([30]), set([10, 20]), set([10, 30]), set([20, 30]), set([10, 20, 30])]

これはnだと思います!時間の複雑さのため、注意してください。これは機能しますが、最も効率的ではない場合があります

0
Shashank Singh