Given a set
{0, 1, 2, 3}
How can I produce the subsets:
[set(),
{0},
{1},
{2},
{3},
{0, 1},
{0, 2},
{0, 3},
{1, 2}
I have found the following algorithm very clear and simple:
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
Another way one can generate the powerset is by generating all binary numbers that have n
bits. As a power set the amount of number with n
digits is 2 ^ n
. The principle of this algorithm is that an element could be present or not in a subset as a binary digit could be one or zero but not both.
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
I found both algorithms when I was taking MITx: 6.00.2x Introduction to Computational Thinking and Data Science, and I consider it is one of the easiest algorithms to understand I have seen.
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
I just wanted to provide the most comprehensible solution, the anti code-golf version.
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
The results
All sets of length 0
[()]
All sets of length 1
[('x',), ('y',), ('z',)]
All sets of length 2
[('x', 'y'), ('x', 'z'), ('y', 'z')]
All sets of length 3
[('x', 'y', 'z')]
For more see the itertools docs, also the wikipedia entry on power sets
Perhaps the question is getting old, but I hope my code will help someone.
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
If you're looking for a quick answer, I just searched "python power set" on google and came up with this: Python Power Set Generator
Here's a copy-paste from the code in that page:
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
This can be used like this:
l = [1, 2, 3, 4]
r = [x for x in powerset(l)]
Now r is a list of all the elements you wanted, and can be sorted and printed:
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(some_set):
res = [(a,b) for a in some_set for b in some_set]
return res