是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?


当前回答

使用cytoolz中的peek函数。

from cytoolz import peek
from typing import Tuple, Iterable

def is_empty_iterator(g: Iterable) -> Tuple[Iterable, bool]:
    try:
        _, g = peek(g)
        return g, False
    except StopIteration:
        return g, True

此函数返回的迭代器将等效于作为参数传入的原始迭代器。

其他回答

在遍历生成器之前检查生成器符合LBYL编码风格。另一种方法(EAFP)是遍历它,然后检查它是否为空。

is_empty = True

for item in generator:
    is_empty = False
    do_something(item)

if is_empty:
    print('Generator is empty')

这种方法也可以很好地处理无限生成器。

有一个非常简单的解决方案:如果next(generator,-1) == -1,那么生成器是空的!

Quick-dirty解决方案:

next(generator, None)不是None

或者将None替换为任何你知道不在生成器中的值。

编辑:是的,这将跳过生成器中的一项。然而,有时我只是出于验证目的检查生成器是否为空,然后并不真正使用它。否则我就会这样做:

def foo(self):
    if next(self.my_generator(), None) is None:
        raise Exception("Not initiated")

    for x in self.my_generator():
        ...

也就是说,如果您的生成器来自一个函数,如my_generator(),则此方法有效。

一种简单的方法是使用next()的可选参数,如果生成器耗尽(或为空),则使用该参数。例如:

_exhausted  = object()

if next(some_generator, _exhausted) is _exhausted:
    print('generator is empty')

这是一个古老的问题,但之前没有人提出过,下面是这个问题:

for _ in generator:
    break
else:
    print('Empty')

你可以在这里阅读更多