I don't really understand how yield
statement works in this situation. The problem says that given an expression without parentheses, write a function to generate all possible fully parenthesized (FP) expressions. Say, the input is '1+2+3+4'
which should be generated to 5 FP expressions:
- (1+(2+(3+4)))
- (1+((2+3)+4))
- ((1+2)+(3+4))
- ((1+(2+3))+4)
- (((1+2)+3)+4)
My code is as follows.
OPS = ('+', '-', '*', '/')
def f(expr):
"""
Generates FP exprs
Recursive formula: f(expr1[op]expr2) = (f(expr1) [op] f(expr2))
"""
if expr.isdigit(): yield expr
# return [expr]
# ret = []
first = ''
i = 0
while i < len(expr):
if expr[i] not in OPS:
first += expr[i]
i += 1
else:
op = expr[i]
i += 1
second = expr[i:]
firstG, secondG = f(first), f(second)
for e in ('(' + e1 + op + e2 + ')' for e1 in firstG for e2 in secondG):
yield e
# ret.append(e)
first += op
# return ret
If I use return
statement (the commented out lines), then the code works as expected. However, when I change to yield
statement as the code shows, I only get the first 4 results. If the number of operands of the input expression is increased, then of course more results will be lost. For example, for the input '1+2+3+4+5'
, I only get 8 instead of 14.
I finally figure out the way to make the code work by commenting out the line firstG, secondG = f(first), f(second)
and replace the line
for e in ('(' + e1 + op + e2 + ')' for e1 in firstG for e2 in secondG):
by
for e in ('(' + e1 + op + e2 + ')' for e1 in f(first) for e2 in f(second)):
That means some 'information' of the generator is lost because of the line firstG, secondG = f(first), f(second)
but I can't figure out the real reason. Could you guys give me some ideas?