首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >发电机“返回”与“产量”之间的差异

发电机“返回”与“产量”之间的差异
EN

Stack Overflow用户
提问于 2014-12-24 18:46:55
回答 2查看 116关注 0票数 0

请看一下代码:

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-24 20:32:14

Python生成器中的返回语句不会执行您认为它所做的事情。这个值不会像在普通函数中那样返回给调用者,而是作为一个属性添加到StopIteration异常上,生成器会引发这个属性,以表示它正在进行迭代。你在循环中看到的行为是不相关的。

首先,让我们理解循环行为。这可以归结为一个简单的事实:循环变量(例如i)在for循环结束时不会超出范围:

代码语言:javascript
复制
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值的去向,如果手动迭代生成器,您可以找到它:

代码语言:javascript
复制
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表达式的结果:

代码语言:javascript
复制
def test3():
    print(yield from test1())

这是一个生成器,它生成与test1相同的值,但它也打印出test1返回的值。

我不认为return成语在大多数情况下是非常有用的。yield from在递归生成器或其他复杂生成器中可能非常有用,但我从未发现需要从一个生成器中获取一个值。

如果您想了解更多关于yield from表达式和生成器返回值的信息,请阅读佩普380,它描述了Python3.3中添加的新特性。

票数 3
EN

Stack Overflow用户

发布于 2014-12-24 20:20:28

有关生成器中的return的讨论,请参阅Blckknght的答案,这是关于for循环中的else子句的。

如果你不喜欢关于for循环中的其他子句的好文章,我就读文档

其要点是,else循环中的for子句都是关于完成的,而不是关于条件的。比较:

代码语言:javascript
复制
if 1:
    print "True"
else:
    print "False"

在这里,当比较结束时执行else子句。但是:

代码语言:javascript
复制
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子句:

代码语言:javascript
复制
for i in xrange(5):
    if i == 4:
        print "Found it!"
        break
else:
    print "Value not in list"
# output: "Found it!"

如果删除break,则将打印这两个字符串。在您的代码中,执行流将始终到达else语句,因此将运行那里的代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27641086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档