如何处理耗尽的迭代器?

ele*_*ent 21 python exception-handling generator python-3.x

在搜索Python文档时,我发现了Pythons内置函数等效python实现.zip()

相反,一个醒目的StopIteration例外,这标志着存在由迭代器不产生其他项目的作者(S)使用的if语句来检查,如果返回的默认值形式next()等于object()(" sentinel")和停止发电机:

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    sentinel = object()
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            elem = next(it, sentinel)

            if elem is sentinel:
                return

            result.append(elem)
        yield tuple(result)
Run Code Online (Sandbox Code Playgroud)

我现在想知道异常捕获或if Python Docs使用语句之间是否有任何区别

或者更好,正如@hiro主角指出的那样:在Python中
使用try考虑EAFP (更容易请求宽恕而不是许可)声明有什么问题

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:

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

            result.append(elem)
        yield tuple(result)
Run Code Online (Sandbox Code Playgroud)

同样,Stoyan Dekov提到" 如果没有异常,则 try/except块非常有效.实际上捕获异常是很昂贵的. "(参见文档以获取更多信息)
但是异常只会发生一次,即迭代器很累.那么异常处理在这种情况下会是更好的解决方案吗?

hir*_*ist 9

你是说与此相反?

def zip2(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            try:
                elem = next(it)
            except StopIteration:
                return

            result.append(elem)
        yield tuple(result)
Run Code Online (Sandbox Code Playgroud)

有趣的问题...我更喜欢这个替代版本 - 特别是考虑到EAFP(更容易要求宽恕而不是许可.)

即使try/except比if语句慢; 这只发生一次 - 只要第一个迭代器耗尽.

值得注意的是,这不是python中的实际实现; 只是一个等同于实际实现的实现.


根据评论更新:

请注意,PEP 479建议return从发电机而不是加油StopIteration.

  • [PEP 479](https://www.python.org/dev/peps/pep-0479/)另有建议......如果我理解正确没有抓住它会暂时有用,但在将来的版本中停止工作. (3认同)

SDe*_*kov 5

通常,在任何编程语言中,提高异常都被认为是一项昂贵的操作 有很多网站可以阅读为什么会这样,我不打算详细介绍它涉及的内容.

来自Python Docs.

如果没有引发异常,try/except块非常有效.实际上捕获异常是昂贵的.

根据情况使用if/elsetry/catch具有其优点和缺点.

  • 例如try/catch,主要用于异常是罕见事件的情况(例如,代码几乎在所有情况下都会成功).
  • 在您的示例中,您知道循环将在每次调用时抛出异常,这使得使用效率非常低 try/catch