与えられたセット
{0, 1, 2, 3}
サブセットを作成するにはどうすればよいですか?
[set(),
{0},
{1},
{2},
{3},
{0, 1},
{0, 2},
{0, 3},
{1, 2},
{1, 3},
{2, 3},
{0, 1, 2},
{0, 1, 3},
{0, 2, 3},
{1, 2, 3},
{0, 1, 2, 3}]
回答:
Pythonitertools
ページには、まさにpowerset
このためのレシピがあります。
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
出力:
>>> list(powerset("abcd"))
[(), ('a',), ('b',), ('c',), ('d',), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd'), ('a', 'b', 'c', 'd')]
最初の空のタプルが気に入らない場合は、range
ステートメントを変更して、range(1, len(s)+1)
長さが0の組み合わせを回避することができます。
s = list(iterable)
必要なのですか?
__len__
実装する必要がないためです。powerset((n for n in range(3)))
リストを折り返すことなく試してみてください。
powerset(range(3))
がなくても問題なく動作しs = list(iterable)
ます。
パワーセットのコードは次のとおりです。これは最初から書かれています:
>>> def powerset(s):
... x = len(s)
... for i in range(1 << x):
... print [s[j] for j in range(x) if (i & (1 << j))]
...
>>> powerset([4,5,6])
[]
[4]
[5]
[4, 5]
[6]
[4, 6]
[5, 6]
[4, 5, 6]
Mark Rushakoffのコメントは、ここに当てはまります。「最初の空のタプルが気に入らない場合は、オンにしてください。」長さ0の組み合わせを回避するには、rangeステートメントをrange(1、len(s)+1)に変更するだけです。 "、私の場合を除いて、あなたはに変更for i in range(1 << x)
しfor i in range(1, 1 << x)
ます。
数年後に戻って、私は今それを次のように書きます:
def powerset(s):
x = len(s)
masks = [1 << i for i in range(x)]
for i in range(1 << x):
yield [ss for mask, ss in zip(masks, s) if i & mask]
そして、テストコードは次のようになります。
print(list(powerset([4, 5, 6])))
使用yield
するということは、1つのメモリですべての結果を計算する必要がないことを意味します。メインループの外側のマスクを事前に計算することは、価値のある最適化であると見なされます。
簡単な答えを探しているなら、私はグーグルで「python power set」を検索して、これを思いついた:Python Power Set Generator
そのページのコードからのコピー&ペーストは次のとおりです。
def powerset(seq):
"""
Returns all the subsets of this set. This is a generator.
"""
if len(seq) <= 1:
yield seq
yield []
else:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item
これは次のように使用できます。
l = [1, 2, 3, 4]
r = [x for x in powerset(l)]
これで、rは必要なすべての要素のリストになり、並べ替えて印刷できます。
r.sort()
print r
[[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 4], [1, 3], [1, 3, 4], [1, 4], [2], [2, 3], [2, 3, 4], [2, 4], [3], [3, 4], [4]]
[[][]]
、長さチェックのケースを分離するだけで修正しますif len(seq) == 0: yield [] elif len(seq) == 1: yield seq yield []
以前に回答を追加したことは知っていますが、新しい実装が本当に気に入っています。セットを入力として使用していますが、実際には反復可能である可能性があり、入力のべき集合であるセットのセットを返します。このアプローチは、べき集合(すべてのサブセットの集合)の数学的定義とより整合しているため、私はこのアプローチが好きです。
def power_set(A):
"""A is an iterable (list, tuple, set, str, etc)
returns a set which is the power set of A."""
length = len(A)
l = [a for a in A]
ps = set()
for i in range(2 ** length):
selector = f'{i:0{length}b}'
subset = {l[j] for j, bit in enumerate(selector) if bit == '1'}
ps.add(frozenset(subset))
return ps
回答に投稿した出力を正確に知りたい場合は、次を使用してください。
>>> [set(s) for s in power_set({1, 2, 3, 4})]
[{3, 4},
{2},
{1, 4},
{2, 3, 4},
{2, 3},
{1, 2, 4},
{1, 2},
{1, 2, 3},
{3},
{2, 4},
{1},
{1, 2, 3, 4},
set(),
{1, 3},
{1, 3, 4},
{4}]
べき集合の要素の数はであることが知られている2 ** len(A)
ので、それはfor
ループではっきりと見ることができます。
入力(理想的にはセット)をリストに変換する必要があります。これは、セットは一意の順序付けされていない要素のデータ構造であり、サブセットを生成するには順序が重要になるためです。
selector
このアルゴリズムの鍵はです。selector
は入力セットと同じ長さであり、これを可能にするために、パディング付きのf文字列を使用していることに注意してください。基本的に、これにより、各反復中に各サブセットに追加される要素を選択できます。入力セットに3つの要素があるとする{0, 1, 2}
と、セレクターは0から7(両端を含む)の値を取ります。これはバイナリでは次のとおりです。
000 # 0
001 # 1
010 # 2
011 # 3
100 # 4
101 # 5
110 # 6
111 # 7
したがって、各ビットは、元のセットの要素を追加する必要があるかどうかのインジケーターとして機能する可能性があります。2進数を見て、各番号をスーパーセットの要素と考えてください。つまり、1
インデックスの要素をj
追加する必要があり0
、この要素を追加しないことを意味します。
集合の内包的性質を使用して、各反復でサブセットを生成し、このサブセットをに変換しfrozenset
て、ps
(べき集合)に追加できるようにします。そうしないと、Pythonのセットは不変オブジェクトのみで構成されているため、追加できません。
いくつかのPython内包表記を使用してコードを単純化できるため、それらのforループを取り除くことができます。インデックスの使用zip
を回避するために使用することもできj
、コードは次のようになります。
def power_set(A):
length = len(A)
return {
frozenset({e for e, b in zip(A, f'{i:{length}b}') if b == '1'})
for i in range(2 ** length)
}
それでおしまい。私がこのアルゴリズムで気に入っitertools
ているのは、期待どおりに機能しているにもかかわらず、信頼できるのは非常に魔法のように見えるため、他のアルゴリズムよりも明確で直感的であるということです。
次のアルゴリズムは非常に明確で単純であることがわかりました。
def get_powerset(some_list):
"""Returns all subsets of size 0 - len(some_list) for some_list"""
if len(some_list) == 0:
return [[]]
subsets = []
first_element = some_list[0]
remaining_list = some_list[1:]
# Strategy: get all the subsets of remaining_list. For each
# of those subsets, a full subset list will contain both
# the original subset as well as a version of the subset
# that contains first_element
for partial_subset in get_powerset(remaining_list):
subsets.append(partial_subset)
subsets.append(partial_subset[:] + [first_element])
return subsets
べき集合を生成する別の方法は、n
ビットを持つすべての2進数を生成することです。べき集合として、n
桁数の数は2 ^ n
です。このアルゴリズムの原則は、2進数が1または0である可能性があるが、両方ではない可能性があるため、要素がサブセットに存在する場合と存在しない場合があることです。
def power_set(items):
N = len(items)
# enumerate the 2 ** N possible combinations
for i in range(2 ** N):
combo = []
for j in range(N):
# test bit jth of integer i
if (i >> j) % 2 == 1:
combo.append(items[j])
yield combo
MITxを使用していたときに両方のアルゴリズムを見つけました:6.00.2x計算的思考とデータサイエンスの概要、そしてそれは私が見た中で最も理解しやすいアルゴリズムの1つだと思います。
def get_power_set(s):
power_set=[[]]
for elem in s:
# iterate over the sub sets so far
for sub_set in power_set:
# add a new subset consisting of the subset at hand added elem
power_set=power_set+[list(sub_set)+[elem]]
return power_set
例えば:
get_power_set([1,2,3])
産出
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
power_set
それが支配するループ内のループ変数()を変更することは、非常に疑わしい方法です。たとえば、提案された変数変更コードの代わりにこれを記述したとしますpower_set += [list(sub_set)+[elem]]
。その後、ループは終了しません。
最もわかりやすいソリューションであるアンチコードゴルフバージョンを提供したかっただけです。
from itertools import combinations
l = ["x", "y", "z", ]
def powerset(items):
combo = []
for r in range(len(items) + 1):
#use a list to coerce a actual list from the combinations generator
combo.append(list(combinations(items,r)))
return combo
l_powerset = powerset(l)
for i, item in enumerate(l_powerset):
print "All sets of length ", i
print item
結果
長さ0のすべてのセット
[()]
長さ1のすべてのセット
[('x',), ('y',), ('z',)]
長さ2のすべてのセット
[('x', 'y'), ('x', 'z'), ('y', 'z')]
長さ3のすべてのセット
[('x', 'y', 'z')]
詳細については、itertoolsのドキュメント、およびパワーセットに関するウィキペディアのエントリを参照してください。
簡単なパワーセットの復習!
セットXのべき集合は、空のセットを含むXのすべてのサブセットのセットです。
セットの例X =(a、b、c)
べき集合= {{a、b、c}、{a、b}、{a、c}、{b、c}、{a}、{b}、{c}、{}}
べき集合を見つける別の方法は次のとおりです。
def power_set(input):
# returns a list of all subsets of the list a
if (len(input) == 0):
return [[]]
else:
main_subset = [ ]
for small_subset in power_set(input[1:]):
main_subset += [small_subset]
main_subset += [[input[0]] + small_subset]
return main_subset
print(power_set([0,1,2,3]))
ソースへの完全なクレジット
簡単な方法は、2の補数演算で整数の内部表現を利用することです。
整数の2進表現は、0から7の範囲の数値の場合は{000、001、010、011、100、101、110、111}です。整数カウンター値の場合、1をコレクション内の対応する要素の包含と見なし、「0」除外として、カウントシーケンスに基づいてサブセットを生成できます。番号から生成されなければならない0
しpow(2,n) -1
Nのバイナリ表現のビットの配列、すなわち数の長さです。
これに基づく簡単なサブセットジェネレータ関数は、次のように記述できます。それは基本的に依存しています
def subsets(array):
if not array:
return
else:
length = len(array)
for max_int in range(0x1 << length):
subset = []
for i in range(length):
if max_int & (0x1 << i):
subset.append(array[i])
yield subset
そしてそれはとして使用することができます
def get_subsets(array):
powerset = []
for i in subsets(array):
powerser.append(i)
return powerset
テスト
ローカルファイルに以下を追加
if __name__ == '__main__':
sample = ['b', 'd', 'f']
for i in range(len(sample)):
print "Subsets for " , sample[i:], " are ", get_subsets(sample[i:])
次の出力を提供します
Subsets for ['b', 'd', 'f'] are [[], ['b'], ['d'], ['b', 'd'], ['f'], ['b', 'f'], ['d', 'f'], ['b', 'd', 'f']]
Subsets for ['d', 'f'] are [[], ['d'], ['f'], ['d', 'f']]
Subsets for ['f'] are [[], ['f']]
これらの回答のほとんどすべてが、list
ではなくを使用set
しています。これは、私には少しごまかしのように感じました。それで、好奇心から、私は本当に簡単なバージョンset
を作成して、他の「Pythonの初心者」の人々のために要約しようとしました。
Pythonのセット実装を扱う際にいくつかの奇妙な点があることがわかりました。私にとっての主な驚きは、空のセットを処理することでした。これは、RubyのSet実装とは対照的です。この実装では、単純に実行Set[Set[]]
して、Set
含まれている1つを空Set
にすることができるため、最初は少し混乱していました。
レビューに、やって中powerset
でset
の、私は2つの問題が発生しました:
set()
iterableを取るので、空のセットiterableが空であるためset(set())
に戻りset()
ます(私は推測します:))set({set()})
そしてset.add(set)
ので動作しませんset()
ハッシュ可能ではありません両方の問題を解決するために、私はを利用しましfrozenset()
た。つまり、私は欲しいものを完全には得られません(タイプは文字通りですset
)が、全体的なset
相互作用を利用します。
def powerset(original_set):
# below gives us a set with one empty set in it
ps = set({frozenset()})
for member in original_set:
subset = set()
for m in ps:
# to be added into subset, needs to be
# frozenset.union(set) so it's hashable
subset.add(m.union(set([member]))
ps = ps.union(subset)
return ps
以下ではfrozenset
、出力として2²(16)が正しく取得されます。
In [1]: powerset(set([1,2,3,4]))
Out[2]:
{frozenset(),
frozenset({3, 4}),
frozenset({2}),
frozenset({1, 4}),
frozenset({3}),
frozenset({2, 3}),
frozenset({2, 3, 4}),
frozenset({1, 2}),
frozenset({2, 4}),
frozenset({1}),
frozenset({1, 2, 4}),
frozenset({1, 3}),
frozenset({1, 2, 3}),
frozenset({4}),
frozenset({1, 3, 4}),
frozenset({1, 2, 3, 4})}
持ってする方法はありませんようset
にset
、あなたがこれらのオンにする場合は、Pythonで秒frozenset
に秒をset
秒、あなたはに戻ってそれらをマッピングする必要がありますlist
(list(map(set, powerset(set([1,2,3,4]))))
)以上を変更します。
質問は古くなっているかもしれませんが、私のコードが誰かに役立つことを願っています。
def powSet(set):
if len(set) == 0:
return [[]]
return addtoAll(set[0],powSet(set[1:])) + powSet(set[1:])
def addtoAll(e, set):
for c in set:
c.append(e)
return set
powerset()
パッケージの関数を使用しますmore_itertools
。
iterableのすべての可能なサブセットを生成します
>>> list(powerset([1, 2, 3]))
[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
セットが必要な場合は、次を使用します。
list(map(set, powerset(iterable)))
再帰を使用してすべてのサブセットを取得します。クレイジーアスワンライナー
from typing import List
def subsets(xs: list) -> List[list]:
return subsets(xs[1:]) + [x + [xs[0]] for x in subsets(xs[1:])] if xs else [[]]
Haskellソリューションに基づく
subsets :: [a] -> [[a]]
subsets [] = [[]]
subsets (x:xs) = map (x:) (subsets xs) ++ subsets xs
NameError: name 'List' is not defined
List
インポート
def findsubsets(s, n):
return list(itertools.combinations(s, n))
def allsubsets(s) :
a = []
for x in range(1,len(s)+1):
a.append(map(set,findsubsets(s,x)))
return a
あなたはこのようにそれを行うことができます:
def powerset(x):
m=[]
if not x:
m.append(x)
else:
A = x[0]
B = x[1:]
for z in powerset(B):
m.append(z)
r = [A] + z
m.append(r)
return m
print(powerset([1, 2, 3, 4]))
出力:
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3], [4], [1, 4], [2, 4], [1, 2, 4], [3, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
これらの答えのどれも実際に実際のPythonセットのリターンを提供しないので、これはワイルドです。これは、実際にはPythonであるパワーセットを提供する厄介な実装ですset
。
test_set = set(['yo', 'whatup', 'money'])
def powerset( base_set ):
""" modified from pydoc's itertools recipe shown above"""
from itertools import chain, combinations
base_list = list( base_set )
combo_list = [ combinations(base_list, r) for r in range(len(base_set)+1) ]
powerset = set([])
for ll in combo_list:
list_of_frozensets = list( map( frozenset, map( list, ll ) ) )
set_of_frozensets = set( list_of_frozensets )
powerset = powerset.union( set_of_frozensets )
return powerset
print powerset( test_set )
# >>> set([ frozenset(['money','whatup']), frozenset(['money','whatup','yo']),
# frozenset(['whatup']), frozenset(['whatup','yo']), frozenset(['yo']),
# frozenset(['money','yo']), frozenset(['money']), frozenset([]) ])
しかし、もっと良い実装が見たいです。
[*map(set, chain.from_iterable(combinations(s, r) for r in range(len(s)+1)))]
。必要に応じて、の関数argを指定map
できますfrozenset
。
これは、組み合わせを使用し、組み込みのみを使用する私の簡単な実装です。
def powerSet(array):
length = str(len(array))
formatter = '{:0' + length + 'b}'
combinations = []
for i in xrange(2**int(length)):
combinations.append(formatter.format(i))
sets = set()
currentSet = []
for combo in combinations:
for i,val in enumerate(combo):
if val=='1':
currentSet.append(array[i])
sets.add(tuple(sorted(currentSet)))
currentSet = []
return sets
セットとしての範囲nのすべてのサブセット:
n = int(input())
l = [i for i in range (1, n + 1)]
for number in range(2 ** n) :
binary = bin(number)[: 1 : -1]
subset = [l[i] for i in range(len(binary)) if binary[i] == "1"]
print(set(sorted(subset)) if number > 0 else "{}")
import math
def printPowerSet(set,set_size):
pow_set_size =int(math.pow(2, set_size))
for counter in range(pow_set_size):
for j in range(set_size):
if((counter & (1 << j)) > 0):
print(set[j], end = "")
print("")
set = ['a', 'b', 'c']
printPowerSet(set,3)
質問のバリエーションは、「コンピュータサイエンスの発見:学際的な問題、原則、およびPythonプログラミング。2015年版」という本で見た演習です。その演習10.2.11では、入力は単なる整数であり、出力はべき集合である必要があります。これが私の再帰的な解決策です(基本的なpython3以外は使用していません)
def powerSetR(n):
assert n >= 0
if n == 0:
return [[]]
else:
input_set = list(range(1, n+1)) # [1,2,...n]
main_subset = [ ]
for small_subset in powerSetR(n-1):
main_subset += [small_subset]
main_subset += [ [input_set[-1]] + small_subset]
return main_subset
superset = powerSetR(4)
print(superset)
print("Number of sublists:", len(superset))
そして出力は
[[]、[4]、[3]、[4、3]、[2]、[4、2]、[3、2]、[4、3、2]、[1]、[4、1 ]、[3、1]、[4、3、1]、[2、1]、[4、2、1]、[3、2、1]、[4、3、2、1]]の数サブリスト:16
私はそのmore_itertools.powerset
機能に出くわしていなかったので、それを使用することをお勧めします。また、からの出力のデフォルトの順序を使用しないことをお勧めします。itertools.combinations
代わりに、位置間の距離を最小化し、距離が大きいアイテムの上/前に、位置間の距離が短いアイテムのサブセットを並べ替えます。
itertools
ページのレシピが使用する番組をchain.from_iterable
r
ここでの下部のための標準的な表記と一致する二項係数を、s
通常と呼ばれるn
(「N Rの選択」)数学テキストおよび計算上def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
ここでの他の例[1,2,3,4]
は、2タプルが「辞書式」順序でリストされるような方法でのべき集合を示しています(数値を整数として出力する場合)。数字の間の距離(つまり差)を書くと、それは私のポイントを示しています:
12 ⇒ 1
13 ⇒ 2
14 ⇒ 3
23 ⇒ 1
24 ⇒ 2
34 ⇒ 1
サブセットの正しい順序は、次のように、最初に最小距離を「使い果たす」順序である必要があります。
12 ⇒ 1
23 ⇒ 1
34 ⇒ 1
13 ⇒ 2
24 ⇒ 2
14 ⇒ 3
ここで数字を使用すると、この順序は「間違っている」ように見えますが、たとえば、この順序でべき集合["a","b","c","d"]
を取得するのになぜこれが役立つのかが明確な文字を考えてみてください。
ab ⇒ 1
bc ⇒ 1
cd ⇒ 1
ac ⇒ 2
bd ⇒ 2
ad ⇒ 3
この効果は、アイテムが多いほど顕著になります。私の目的では、べき集合のインデックスの範囲を意味のある形で記述できるかどうかに違いがあります。
(組み合わせ論におけるアルゴリズムの出力順序については、グレイコードなどで書かれていることがたくさんありますが、副次的な問題ではないと思います)。
私は実際に、この高速整数パーティションコードを使用して値を適切な順序で出力するかなり複雑なプログラムを作成しましたが、その後、次のmore_itertools.powerset
ようにその関数を使用するだけで問題ないことがわかりました。
from more_itertools import powerset
from numpy import ediff1d
def ps_sorter(tup):
l = len(tup)
d = ediff1d(tup).tolist()
return l, d
ps = powerset([1,2,3,4])
ps = sorted(ps, key=ps_sorter)
for x in ps:
print(x)
⇣
()
(1,)
(2,)
(3,)
(4,)
(1, 2)
(2, 3)
(3, 4)
(1, 3)
(2, 4)
(1, 4)
(1, 2, 3)
(2, 3, 4)
(1, 2, 4)
(1, 3, 4)
(1, 2, 3, 4)
(:かなり私はここに含まれていませんでした機能を印刷するためのレポを参照してください、私はきれいにPowersetのが印刷されますいくつかのより複雑なコードを書いたprint_partitions
、print_partitions_by_length
とpprint_tuple
)。
pset_partitions.py
これはすべて非常に単純ですが、パワーセットのさまざまなレベルに直接アクセスできるコードが必要な場合は、それでも役立つ可能性があります。
from itertools import permutations as permute
from numpy import cumsum
# http://jeromekelleher.net/generating-integer-partitions.html
# via
# /programming/10035752/elegant-python-code-for-integer-partitioning#comment25080713_10036764
def asc_int_partitions(n):
a = [0 for i in range(n + 1)]
k = 1
y = n - 1
while k != 0:
x = a[k - 1] + 1
k -= 1
while 2 * x <= y:
a[k] = x
y -= x
k += 1
l = k + 1
while x <= y:
a[k] = x
a[l] = y
yield tuple(a[:k + 2])
x += 1
y -= 1
a[k] = x + y
y = x + y - 1
yield tuple(a[:k + 1])
# https://stackoverflow.com/a/6285330/2668831
def uniquely_permute(iterable, enforce_sort=False, r=None):
previous = tuple()
if enforce_sort: # potential waste of effort (default: False)
iterable = sorted(iterable)
for p in permute(iterable, r):
if p > previous:
previous = p
yield p
def sum_min(p):
return sum(p), min(p)
def partitions_by_length(max_n, sorting=True, permuting=False):
partition_dict = {0: ()}
for n in range(1,max_n+1):
partition_dict.setdefault(n, [])
partitions = list(asc_int_partitions(n))
for p in partitions:
if permuting:
perms = uniquely_permute(p)
for perm in perms:
partition_dict.get(len(p)).append(perm)
else:
partition_dict.get(len(p)).append(p)
if not sorting:
return partition_dict
for k in partition_dict:
partition_dict.update({k: sorted(partition_dict.get(k), key=sum_min)})
return partition_dict
def print_partitions_by_length(max_n, sorting=True, permuting=True):
partition_dict = partitions_by_length(max_n, sorting=sorting, permuting=permuting)
for k in partition_dict:
if k == 0:
print(tuple(partition_dict.get(k)), end="")
for p in partition_dict.get(k):
print(pprint_tuple(p), end=" ")
print()
return
def generate_powerset(items, subset_handler=tuple, verbose=False):
"""
Generate the powerset of an iterable `items`.
Handling of the elements of the iterable is by whichever function is passed as
`subset_handler`, which must be able to handle the `None` value for the
empty set. The function `string_handler` will join the elements of the subset
with the empty string (useful when `items` is an iterable of `str` variables).
"""
ps = {0: [subset_handler()]}
n = len(items)
p_dict = partitions_by_length(n-1, sorting=True, permuting=True)
for p_len, parts in p_dict.items():
ps.setdefault(p_len, [])
if p_len == 0:
# singletons
for offset in range(n):
subset = subset_handler([items[offset]])
if verbose:
if offset > 0:
print(end=" ")
if offset == n - 1:
print(subset, end="\n")
else:
print(subset, end=",")
ps.get(p_len).append(subset)
for pcount, partition in enumerate(parts):
distance = sum(partition)
indices = (cumsum(partition)).tolist()
for offset in range(n - distance):
subset = subset_handler([items[offset]] + [items[offset:][i] for i in indices])
if verbose:
if offset > 0:
print(end=" ")
if offset == n - distance - 1:
print(subset, end="\n")
else:
print(subset, end=",")
ps.get(p_len).append(subset)
if verbose and p_len < n-1:
print()
return ps
例として、コマンドライン引数として文字列を受け取るCLIデモプログラムを作成しました。
python string_powerset.py abcdef
⇣
a, b, c, d, e, f
ab, bc, cd, de, ef
ac, bd, ce, df
ad, be, cf
ae, bf
af
abc, bcd, cde, def
abd, bce, cdf
acd, bde, cef
abe, bcf
ade, bef
ace, bdf
abf
aef
acf
adf
abcd, bcde, cdef
abce, bcdf
abde, bcef
acde, bdef
abcf
abef
adef
abdf
acdf
acef
abcde, bcdef
abcdf
abcef
abdef
acdef
abcdef
特定の長さのサブセットが必要な場合は、次のように実行できます。
from itertools import combinations
someSet = {0, 1, 2, 3}
([x for i in range(len(someSet)+1) for x in combinations(someSet,i)])
より一般的には、任意の長さのサブセットの場合、範囲の長さを変更できます。出力は
[()、(0、)、(1、)、(2、)、(3、)、(0、1)、(0、2)、(0、3)、(1、2)、(1 、3)、(2、3)、(0、1、2)、(0、1、3)、(0、2、3)、(1、2、3)、(0、1、2、3 )]
これが私の解決策です。これは(概念的には)lmiguelvargasfの解決策と似ています。
-[数学項目]定義により、べき集合には空の集合-[個人的な好み]が含まれていること、また、frozensetを使用するのは好きではないと言わせてください。
したがって、入力はリストであり、出力はリストのリストになります。関数はもっと早く閉じることができますが、べき集合の要素が辞書式順序であることが好きです。つまり、本質的にはうまく意味します。
def power_set(L):
"""
L is a list.
The function returns the power set, but as a list of lists.
"""
cardinality=len(L)
n=2 ** cardinality
powerset = []
for i in range(n):
a=bin(i)[2:]
subset=[]
for j in range(len(a)):
if a[-j-1]=='1':
subset.append(L[j])
powerset.append(subset)
#the function could stop here closing with
#return powerset
powerset_orderred=[]
for k in range(cardinality+1):
for w in powerset:
if len(w)==k:
powerset_orderred.append(w)
return powerset_orderred
def powerset(some_set):
res = [(a,b) for a in some_set for b in some_set]
return res