値のセットがあり、2つの要素を含むすべてのサブセットのリストを作成したいと思います。
たとえば、ソースセット([1,2,3])
には、次の2要素のサブセットがあります。
set([1,2]), set([1,3]), set([2,3])
Pythonでこれを行う方法はありますか?
あなたが望むようです itertools.combinations
:
>>> list(itertools.combinations((1, 2, 3), 2))
[(1, 2), (1, 3), (2, 3)]
セットが必要な場合は、明示的に変換する必要があります。リストの代わりに反復可能を気にせず、Python 3を使用している場合は、map
を使用できます:
>>> s = set((1, 2, 3))
>>> map(set, itertools.combinations(s, 2))
<map object at 0x10cdc26d8>
すべての結果を一度に表示するには、map
の出力をlist
に渡すことができます。 (Python 2では、map
の出力は自動的にリストになります。)
>>> list(map(set, itertools.combinations(s, 2)))
[{1, 2}, {1, 3}, {2, 3}]
ただし、リストが必要であることがわかっている場合は、リストの理解がわずかに向上します(h/t Jacob Bowyer ):
>>> [set(i) for i in itertools.combinations(s, 2)]
[{1, 2}, {1, 3}, {2, 3}]
これは、すべての2要素セットを含む{1, 2, 3}
(または任意のセット)の べき集合 のサブセットです。
Python itertools
ドキュメント を参照し、「べき集合」という用語でこの問題の一般的な答えを検索してください。
別の見方をするために、私は_{1.....N}
_のサイズ2のすべてのサブセットを反復する方法を探したので、_itertools.combinations
_をテストしました。
_import itertools
from time import time
N = 7000
lst = [i for i in xrange(N)]
st = time()
c1 = 0
for x in itertools.combinations(lst, 2):
c1 += 1
print "combinations: %f" % (time()-st)
st = time()
c2=0
for x in xrange(N):
for y in xrange(x):
c2 += 1
print "double loop: %f" % (time()-st)
print "c1=%d,c2=%d" % (c1,c2)
# prints:
#combinations: 4.247000
#double loop: 3.479000
# c1=24496500,c2=24496500
_
したがって、常に一般的な解決策になるとは限らないと思います。必要なサブセットのサイズが事前にわかっている場合は、forループを使用して反復する方が効率的です。
また、この移動によりリストが作成されるため、list(itertools.combinations(lst, 2))
を反復処理しないでください(ジェネレーター自体を使用するよりもはるかに低速です)。