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


当前回答

Bool (generator)将返回正确的结果

其他回答

我用求和函数解出来了。请参阅下面我使用glob的示例。Iglob(返回一个生成器)。

def isEmpty():
    files = glob.iglob(search)
    if sum(1 for _ in files):
        return True
    return False

*这可能不适用于巨大的生成器,但对于较小的列表应该表现得很好

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(),则此方法有效。

为了表达我的“2美分”,我将描述一下我的经历:

我有一个生成器,我需要用itertools切片它。分成小发电机。然后检查我的子生成器是否为空,我只是将它们转换/消耗到一个小列表中,然后检查列表是否为空。

例如:

from itertools import islice

def generator(max_yield=10):
    a = 0

    while True:
        a += 1

        if a > max_yield:
            raise StopIteration()

        yield a

tg = generator()

label = 1

while True:
    itg = list(islice(tg, 3))

    if not itg:  # <-- I check if the list is empty or not
        break

    for i in itg:
        print(f'#{label} - {i}')

    label += 1

输出:

#1 - 1
#1 - 2
#1 - 3
#2 - 4
#2 - 5
#2 - 6
#3 - 7
#3 - 8
#3 - 9
#4 - 10

也许这不是最好的方法,主要是因为它会消耗生成器,但对我来说却是可行的。

如果你在使用生成器之前需要知道,那么不,没有简单的方法。如果你可以等到你使用生成器之后,有一个简单的方法:

was_empty = True

for some_item in some_generator:
    was_empty = False
    do_something_with(some_item)

if was_empty:
    handle_already_empty_generator_case()

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

_exhausted  = object()

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