收益率与回报的不同结果 [英] Different results from yield vs return
问题描述
我真的不明白 yield
语句在这种情况下是如何工作的.问题是给定一个没有括号的表达式,编写一个函数来生成所有可能的全括号 (FP) 表达式.假设输入是 '1+2+3+4'
应该生成 5 个 FP 表达式:
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)
我的代码如下.
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
如果我使用 return
语句(注释掉的行),则代码按预期工作.但是,当我更改为代码所示的 yield
语句时,我只能得到前 4 个结果.如果输入表达式的操作数增加,那么当然会丢失更多的结果.例如,对于输入'1+2+3+4+5'
,我只得到8而不是14.
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.
我终于找到了通过注释掉 firstG, secondG = f(first), f(second)
行并替换该行来使代码工作的方法
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):
由
for e in ('(' + e1 + op + e2 + ')' for e1 in f(first) for e2 in f(second)):
这意味着由于行 firstG, secondG = f(first), 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?
推荐答案
问题是你在 yield 版本中迭代生成器而不是列表,特别是 secondG ,它在一个循环后耗尽.将行更改为此,它的工作原理:
The problem is you're iterating over generators instead of lists in the yield version, specifically secondG which is exhausted after one loop. Change the line to this and it works:
firstG, secondG = f(first), list(f(second))
或者,您可以更改循环:
Or, you can change your loop:
for e in ("(%s%s%s)" % (e1, op, e2) for e1 in f(first) for e2 in f(second)):
# new generator object every loop ^^^^^^^^^
非yield 版本有效,因为您返回列表,与生成器不同,它可以再次迭代.另请注意,您只迭代 firstG 一次,因此不受影响.
The non-yield version works because you return lists, which can be iterated over again, unlike generators. Also note you only iterate over firstG once, so it's not affected.
记住这一点:
r = [v for a in A for b in B]
相当于:
r = []
for a in A:
for b in B:
r.append(v)
哪个更清楚地显示了 B 上的重复循环.
Which more clearly shows the repeated loop over B.
另一个例子:
def y():
yield 1
yield 2
yield 3
def r():
return [1, 2, 3]
vy = y()
for v in vy:
print v
for v in vy:
print v
print "---"
vr = r()
for v in vr:
print v
for v in vr:
print v
这篇关于收益率与回报的不同结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!