I'm trying to generate a powerset of a large list of strings that includes replacements. None of the built-in itertools functions do this (as far as I can tell).
EDIT Maybe using "set" in the title was misleading. Order is important here. 'ca' != 'ac'
Example of what I want:
print( powerset_with_replacement(['abc']) )
# yeilds
('a',)
('b',)
('c',)
('a', 'a')
('a', 'b')
('a', 'c')
('b', 'b')
('b', 'c')
('c', 'c')
('a', 'a', 'a')
('a', 'a', 'b')
('a', 'a', 'c')
('a', 'b', 'b')
('a', 'b', 'c')
('a', 'c', 'c')
('b', 'b', 'b')
('b', 'b', 'c')
('b', 'c', 'c')
('c', 'c', 'c')
I got this far already but it seems messy.. I'm wondering if there is a cleaner or more pythonic way to do this. Any help is much appreciated.
Is there a way to get rid of the flatten function or put that inside the main one?
from itertools import combinations_with_replacement
import collections
def flatten(it):
for x in it:
if (isinstance(x, collections.abc.Iterable) and
not isinstance(x, tuple)):
yield from flatten(x)
else:
yield x
def powerset_with_replacement(list1):
for i in range(1,len(list1)+1):
yield( combinations_with_replacement(list1, i) )
y = flatten(powerset_with_replacement(list('abc')))
for x in y:
print(x)