代码之家  ›  专栏  ›  技术社区  ›  James Brady

在Python生成器中用于…else

  •  7
  • James Brady  · 技术社区  · 17 年前

    for...else syntax -令人惊讶的是,它的应用频率和简化代码的效率。

    def iterate(i):
        for value in i:
            yield value
        else:
            print 'i is empty'
    

    在上面的例子中,我希望 print 仅在以下情况下执行的语句 i else 只尊重 break return ,它总是被执行,而不管

    如果无法使用 for...else 在这种情况下,最好的方法是什么

    6 回复  |  直到 15 年前
        1
  •  11
  •   Kenan Banks    17 年前

    您正在破坏生成器的定义,当迭代完成时,它应该抛出StopIteration异常(由生成器函数中的返回语句自动处理)

    因此:

    def iterate(i):
        for value in i:
            yield value
        return
    

    最好让调用代码处理空迭代器的情况:

    count = 0
    for value in iterate(range([])):
        print value
        count += 1
    else:
        if count == 0:
            print "list was empty"
    

    这可能是一种更简洁的方法,但它应该可以很好地工作,并且不属于下面常见的“将迭代器当作列表”陷阱。

        2
  •  5
  •   Chris B.    17 年前

    有几种方法可以做到这一点。你可以随时使用 Iterator 直接:

    def iterate(i):
        try:
            i_iter = iter(i)
            next = i_iter.next()
        except StopIteration:
            print 'i is empty'
            return
    
        while True:
            yield next
            next = i_iter.next()
    

    但是如果你知道更多关于这场争论的内容 i ,你可以更简洁:

    def iterate(i):
        if i:  # or if len(i) == 0
            for next in i:
                yield next
        else:
            print 'i is empty'
            raise StopIteration()
    
        3
  •  5
  •   Ber    17 年前

    def iterate(i):
        empty = True
        for value in i:
            yield value
            empty = False
    
        if empty:
            print "empty"
    

    因此,实际上不涉及“其他”条款。

        4
  •  4
  •   Beni Cherniavsky-Paskin    16 年前

    正如你所注意到的, for..else 只检测到一个 break .

    它不适用于你的目的不是因为它是发电机,而是 (因为你想全部放弃,但这不是重点)。

        5
  •  0
  •   Mykola Kharechko    17 年前

    如果不可能用于…或者以这种方式,那么最好的方法是什么,以便只在不产生任何结果的情况下执行print语句?

    我能想到的最大值是:

    
    >>> empty = True
    >>> for i in [1,2]:
    ...     empty = False
    ... if empty:
    ...     print 'empty'
    ...
    >>>
    >>>
    >>> empty = True
    >>> for i in []:
    ...     empty = False
    ... if empty:
    ...    print 'empty'
    ...
    empty
    >>>
    
    
        6
  •  -2
  •   Martin Janiczek    17 年前

    如果还有简单的呢?

    def iterate(i):
        if len(i) == 0: print 'i is empty'
        else:
            for value in i:
                yield value