Here's an interesting way to do it, though I'd still go with the itertools solution.
Notice that the list of strings you produce is morally a binary tree: at each instance of the replacement character in the string you either want to ignore it ("go left") or replace it ("go right"). So you can make a binary tree structure out of the replacement strings. Walking the leaves of a binary tree is easy.
class ReplacementTree(object):
def __init__(self, s, src, target, prefix=""):
self.leaf = src not in s
if 1 == len(s.split(src, 1)):
self.head, self.tail = s, ""
else:
self.head, self.tail = s.split(src, 1)
self.prefix, self.src, self.target = prefix, src, target
@property
def value(self):
if self.leaf:
return self.prefix + self.head
@property
def left(self):
if self.leaf:
return None
else:
return ReplacementTree(self.tail,
self.src,
self.target,
prefix=self.prefix + self.head + self.src)
@property
def right(self):
if self.leaf:
return None
else:
return ReplacementTree(self.tail,
self.src,
self.target,
prefix=self.prefix + self.head + self.target)
def leaves(tree):
if tree.leaf:
yield tree.value
else:
for leaf in leaves(tree.left):
yield leaf
for leaf in leaves(tree.right):
yield leaf
Example:
>>> x = repltree.ReplacementTree("thruput", "u", "ough")
>>> list(repltree.leaves(x))
['thruput', 'thrupought', 'throughput', 'throughpought']