在 Python 中获取一个集合的所有子集(幂集)
Get all subsets of a Set in Python (Powerset)
使用itertools
文档中的方法获取 a 的所有子集
set
。
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)) # print(list(combinations([1, 2, 3], 2))) my_set = {1, 2, 3} # 👇️ [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] print(list(powerset(my_set)))
该powerset
配方在
文档的这一部分中可用。
itertools.combinations()方法采用
可迭代和长度参数。
该方法从 iterable 返回长度为 N 的元素的子序列。
from itertools import combinations # 👇️ [()] print(list(combinations([1, 2, 3], 0))) # 👇️ [(1,), (2,), (3,)] print(list(combinations([1, 2, 3], 1))) # 👇️ [(1, 2), (1, 3), (2, 3)] print(list(combinations([1, 2, 3], 2))) # 👇️ [(1, 2, 3)] print(list(combinations([1, 2, 3], 3)))
最后一步是使用
chain.from_iterable
方法。
该方法从可迭代对象中获取链式输入,例如['ABC', 'DEF']
变成
A B C D E F
.
from itertools import chain # 👇️ [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3)] print(list(chain.from_iterable([ [()], [(1,), (2,), (3,)], [(1, 2), (1, 3), (2, 3)], ])))
The chain.from_iterable()
method returns a chain
object. Use the list()
class to convert it to a list of tuples if necessary.
Alternatively, you can define your own function.
def powerset(iterable): l = list(iterable) result = [tuple()] for item in l: result += [tup + (item,) for tup in result] return result my_set = {1, 2, 3} # [(), (1,), (2,), (1, 2), (3,), (1, 3), (2, 3), (1, 2, 3)] print(powerset(my_set))
The function converts the set
to a list and uses a for
loop to iterate over
the list.
On each iteration, we use a list comprehension to iterate over the result
variable. The result
variable stores a list of tuples.
We used the addition (+) operator to combine two lists of tuples.
print([()] + [(1, 2)]) # 👉️ [(), (1, 2)] print((1, 2) + (3, 4)) # 👉️ (1, 2, 3, 4)
We also used the operator to combine the elements of two tuples into a single
tuple.
Which approach you pick is a matter of personal preference. I’d use the recipe
from the documentation as it is quite performant, tried and tested.