如何得到一个集合的所有子集? (电源集)

给我一套

{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}]
210328 次浏览

Python itertools恰好有一个 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长度的组合。

下面是一个电源组的更多代码,这是从头开始编写的:

>>> 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 的评论在这里是适用的: “如果你不喜欢开头的空元组,在。“您可以将 range 语句更改为 range (1,len (s) + 1)以避免0长度组合”,但在我的例子中,您可以将 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意味着不需要在一块内存中计算所有结果。在主循环之外预先计算掩码被认为是一个有价值的优化。

如果你正在寻找一个快速的答案,我刚刚在谷歌搜索“巨蟒电源设置”,得到了这个: Python 动力装置发生器

下面是从该页面的代码复制粘贴的内容:

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]]
def powerset(lst):
return reduce(lambda result, x: result + [subset + [x] for subset in result],
lst, [[]])

我只是想提供最易理解的解决方案,反代码高尔夫版本。

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 文档,也可以查看维基百科关于 发电机组的条目

这很疯狂,因为这些答案实际上都没有提供实际 Python 集的返回值。下面是一个混乱的实现,它将提供一个实际上是 Pythonset的 Powerset。

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([]) ])

不过,我希望看到更好的实现。

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]]

这里是我的快速实现利用组合,但只使用内置。

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

动力系统有一个改进:

def powerset(seq):
"""
Returns all the subsets of this set. This is a generator.
"""
if len(seq) <= 0:
yield []
else:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item

我发现下面的算法非常简单明了:

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位的所有二进制数。作为一个功率集的数量与 n数字是 2 ^ n。该算法的原理是,一个元素可以存在或不存在于一个子集中,因为二进制数字可以是一个或零,但不能是二者兼而有之。

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.2 x 时,我发现了这两种算法。计算思维和数据科学入门,我认为这是我见过的最容易理解的算法之一。

只是一个快速的电力设置复习!

集合 X 的幂集,是包括 空的布景

示例集 X = (a,b,c)

幂集 = { a,b,c } ,{ 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的补数算法下的整数的内部表示。

对于0到7之间的数字,整数的二进制表示形式为{000,001,010,011,100,101,110,111}。对于一个整数计数器值,考虑集合中包含1作为对应元素,排除’0’作为对应元素,我们可以根据计数序列生成子集。数字必须从 0pow(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']]

DR (直接转到简化)

我知道我之前已经添加了一个答案,但是我真的很喜欢我的新实现。我将一个集合作为输入,但它实际上可以是任何可迭代的,并且我返回一个集合集合,它是输入的幂集。我喜欢这种方法,因为它更符合 动力装置(所有子集的集合)的数学定义。

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},因此 selector 将获取0到7之间的值(包括0和7) ,这些值在二进制中是:

000 # 0
001 # 1
010 # 2
011 # 3
100 # 4
101 # 5
110 # 6
111 # 7

因此,如果应该添加或不应该添加原始集合中的元素,则每个位都可以作为指示器。查看二进制数,只需将每个数看作超集的一个元素,其中 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 subsets(iterable):
for n in range(len(iterable) + 1):
yield from combinations(iterable, n)

几乎所有的答案都使用 list而不是 set,这让我觉得有点像作弊。因此,出于好奇,我试图在 set上做一个简单的版本,并为其他“ Python 新手”做总结。

我发现在处理 Python 的 设定实施时有一些奇怪的地方。最让我惊讶的是处理空集。这与 Ruby 的 设置实现形成了鲜明的对比,在 设置实现中,我可以简单地执行 Set[Set[]]并得到一个包含一个空 SetSet,所以我最初发现它有点令人困惑。

回顾一下,在用 setpowerset时,我遇到了两个问题:

  1. set()采用迭代,因此 set(set())将返回 set() 因为空集迭代是空的(我猜是:)
  2. 为了得到一组集合,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

下面我们得到22(16)个 frozenset作为输出:

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})}

因为在 Python 中不可能有 setset,所以如果你想把这些 frozenset转换成 set,你必须把它们映射回 list(< code > 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

使用包 more_itertools中的函数 powerset()

产生迭代的所有可能的子集

>>> 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
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

设置范围 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 编程》一书中看到的练习。二零一五年版」。在练习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] ,[3,2,1] ,[4,3,2,1] ,[3,2,1] ,[4,3,2,1] 分列名单数目: 16

我还没有遇到 more_itertools.powerset函数,所以建议使用它。我还建议不要使用 itertools.combinations输出的默认顺序,通常情况下,你想要最小化位置之间的 距离,并且在它们之间的距离较短的项目之前,在它们之间的距离较大的项目之前,对它们的子集进行排序。

itertools食谱页显示它使用 chain.from_iterable

  • 请注意,这里的 r二项式系数下半部分的标准符号相匹配,s在数学课本和计算器上通常被称为 n(“ n Select 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

对于更多的条目,这种效果更加明显,对于我来说,它决定了是否能够有意义地描述 Powerset 的索引范围。

(灰色代码上有很多关于组合数学算法输出顺序的文章,我不认为这是一个边缘问题)。

实际上,我刚刚编写了一个相当复杂的程序,它使用这个快速整数分区代码以正确的顺序输出值,但是后来我发现了 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)

Something

()
(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)

我写了一些更复杂的代码,这些代码可以很好地打印电源集(参见我在这里没有包含的漂亮打印函数: print_partitionsprint_partitions_by_lengthpprint_tuple的回购文件)。

这些都很简单,但是如果你想要一些代码让你直接访问不同级别的 Powerset,这些代码还是很有用的:

from itertools import permutations as permute
from numpy import cumsum


# http://jeromekelleher.net/generating-integer-partitions.html
# via
# https://stackoverflow.com/questions/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

Something

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,3) ,(2,3) ,(0,1,2) ,(0,1,3) ,(0,2,3) ,(1,2,3)]

你可以这样做:

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]]

这可以通过 itertools.product非常自然地完成:

import itertools


def powerset(l):
for sl in itertools.product(*[[[], [i]] for i in l]):
yield {j for i in sl for j in i}

我知道太迟了

已经有很多其他的解决方案,但仍然..。

def power_set(lst):
pw_set = [[]]


for i in range(0,len(lst)):
for j in range(0,len(pw_set)):
ele = pw_set[j].copy()
ele = ele + [lst[i]]
pw_set = pw_set + [ele]


return pw_set
def powerset(some_set):
res = [(a,b) for a in some_set for b in some_set]
return res

这里是我的解,它与 lMiguelvargasf 的解(概念上)相似。

这么说吧 根据定义,Powerset 确实包含空集 - [个人品味]而且我不喜欢使用冷冻模式。

所以输入是一个列表,输出将是一个列表列表。函数可以更早关闭,但是我希望幂的元素设置为 按字典顺序顺序,这本质上意味着很好。

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
from itertools import combinations
def subsets(arr: set) -> list:
subsets = []
[subsets.extend(list(combinations(arr,n))) for n in range(len(arr))]
return subsets


a = {1,2,3}
print(subsets(a))

产出:

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

对于已排序的子集,我们可以这样做:

# sorted subsets
print(sorted(subsets(a)))

产出:

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