请看一下代码:
def main():
for p in test1(): print(p)
def test1():
s = set()
s.update(range(5))
for p in s: yield p
return s为什么我只有0,1,2,3,4?产出应为: 0,1,2,3,4倍(1倍为“产量”,1倍为“回报”)
PS: Python-3.4
发布于 2014-12-24 20:32:14
Python生成器中的返回语句不会执行您认为它所做的事情。这个值不会像在普通函数中那样返回给调用者,而是作为一个属性添加到StopIteration异常上,生成器会引发这个属性,以表示它正在进行迭代。你在循环中看到的行为是不相关的。
首先,让我们理解循环行为。这可以归结为一个简单的事实:循环变量(例如i)在for循环结束时不会超出范围:
for i in range(5): # this loop will print 0 through 4
print(i)
print(i) # this line will print 4 again, since 4 it was the last value assigned to i你的代码就是这么做的。您使用的else子句没有什么特别之处,因为您从未脱离循环。(Neftas的回答解释了附加到循环的else是为了什么。)
至于return值的去向,如果手动迭代生成器,您可以找到它:
gen = test1()
print(next(gen)) # prints 0
print(next(gen)) # prints 1
print(next(gen)) # prints 2
print(next(gen)) # prints 3
print(next(gen)) # prints 4
print(next(gen)) # prints set([0,1,2,3,4]) from the last yield statement
try:
next(gen)
except StopIteration as e:
print(e.value) # prints set([0,1,2,3,4]) from the return statement这不是一个很常见的用法。获取返回值的通常方法是在另一个生成器中使用yield from表达式的结果:
def test3():
print(yield from test1())这是一个生成器,它生成与test1相同的值,但它也打印出test1返回的值。
我不认为return成语在大多数情况下是非常有用的。yield from在递归生成器或其他复杂生成器中可能非常有用,但我从未发现需要从一个生成器中获取一个值。
如果您想了解更多关于yield from表达式和生成器返回值的信息,请阅读佩普380,它描述了Python3.3中添加的新特性。
发布于 2014-12-24 20:20:28
有关生成器中的return的讨论,请参阅Blckknght的答案,这是关于for循环中的else子句的。
如果你不喜欢关于for循环中的其他子句的好文章,我就读文档。
其要点是,else循环中的for子句都是关于完成的,而不是关于条件的。比较:
if 1:
print "True"
else:
print "False"在这里,当比较结束时执行else子句。但是:
for i in xrange(5):
if i == 123:
print "Found it!"
break
else:
print "Value not in list"
# output: "Value not in list"在这里,除非执行流击中else语句,否则将执行break子句:
for i in xrange(5):
if i == 4:
print "Found it!"
break
else:
print "Value not in list"
# output: "Found it!"如果删除break,则将打印这两个字符串。在您的代码中,执行流将始终到达else语句,因此将运行那里的代码。
https://stackoverflow.com/questions/27641086
复制相似问题