Python 生成器实现方式问题

def accumulate(iterable, func=operator.add):

'Return running totals'
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
try:
    total = next(it)
except StopIteration:
    return
yield total
for element in it:
    total = func(total, element)
    yield total
    
    

这是Python文档关于 itertools.accumulate 函数的说明
https://docs.python.org/zh-cn...

在我的理解里(应该是错误的理解),total = next(it)总会取到第一个值,而永远不会抛出异常,谁能告诉会抛出这个异常的实例呢?

请问在什么情况下,调用这个函数会抛出StopIteration异常呢,传入一个可迭代对象实参后,try: total=next(it),不是应该总是可以取到第一个元素吗,为什么需要except StopIteration呢,在什么情况下才会抛出这个异常呢?

感谢回答,我明白next取不到下一个元素的时候就抛出StopIteration,但是这段代码运行后取一次next然后就会进入for element in it: 的这个循环中,并在这个循环结束时就结束这个函数.而不会再执行上面的next,那么怎么会抛出stopIteration呢?可以具个具体的实例吗

就是说next在这段代码中是否只会执行一次呢,而执行一次的话,不是应该"总是"可以取到第一个元素而不会抛出异常吗?

阅读 2k
2 个回答

关于生成器的StopIteration异常,以前做过一个回答,可以看下:https://segmentfault.com/q/10...

这段代码里的

try:
    total = next(it)
except StopIteration:
    return

主要处理可迭代对象为空的情况,你可以试试下面的代码会不会抛出StopIteration异常

a = iter([])
next(a)

如果可迭代对象为空,return掉,accumulate构造的生成器也是空的,如果可迭代对象不空,total就是第一元素,第一次当然要yield出去,之后的代码就不需要解释了。

当next取不到下一个元素的时候就会出现StopIteration,其实就是说StopIteration是作为一个列表遍历的结尾标识存在的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题