It is called a power set (in your case the empty set is excluded).
To build a power set, start with a set with an empty set in it; then
for each item in the input set extend the power set with all its subsets accumulated so far
with the current item included (in Python):
def powerset(lst):
S = [[]]
for item in lst:
S += [subset + [item] for subset in S]
return S
Example:
print(powerset([1, 2, 3]))
# -> [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
To avoid producing all subsets at once, a recursive definition could be used:
- a power set of an empty set is a set with an empty set in it
- a power set of a set with
n
items contains all subsets from a power set
of a set with n - 1
items plus all these subsets with the n
-th item included.
def ipowerset(lst):
if not lst: # empty list
yield []
else:
item, *rest = lst
for subset in ipowerset(rest):
yield subset
yield [item] + subset
Example:
print(list(ipowerset([1, 2, 3])))
# -> [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Yet another way to generate a power set is to generate r
-length subsequences (combinations) for all r
from zero to the size of the input set (itertools
recipe):
from itertools import chain, combinations
def powerset_comb(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
Example:
print(list(powerset_comb([1, 2, 3])))
# -> [(), (1,), (2,), (3,), (1,2), (1,3), (2,3), (1,2,3)]
See also what's a good way to combinate through a set?.