检测生成器函数是否为空,否则迭代它

问题描述 投票:0回答:3

假设我们有一个生成器函数

gen()
,我们不知道它是否为空。

如果它是空的,我们想执行一个特殊的函数

foo()
,否则我们想对迭代器的每个元素执行一个函数
bar(elem)

我可以这样做:

is_empty = True
for elem in gen():
    is_empty = False
    bar(elem)
if is_empty: foo()

但这感觉不太Pythonic。还有其他办法吗?

python python-3.x generator iterable
3个回答
2
投票

你无法直接判断生成器是否为空。这是设计使然。生成器背后的一个关键原则是它们不会在内存中保存生成序列的所有项目。

但是你可以这样做:

from itertools import chain

def check_first_and_iterate(iterable):
    try:
        first = next(iterable)
        for item in chain([first], item):
            bar(item)
    except StopIteration:
        foo()

check_first_and_iterate(iterable)

2
投票

peek
功能:

import itertools
def peek(iterable):
    try:
        first = next(iterable)
    except StopIteration:
        return None
    return first, itertools.chain([first], iterable)

res = peek(gen())
if not res:
    foo()
else:
    for elem in res[1]:
        bar(elem)

您仍然需要查看生成器,但您可以干净利落地完成。


0
投票

如果您有能力在遍历生成器的项目之前耗尽生成器,并且您的函数

foo()
返回
None
,您可以考虑这样做:

for elem in list(gen()) or foo() or []:
    bar(elem)

仅当第一个操作数为假时,

or
运算符才计算第二个操作数。

© www.soinside.com 2019 - 2024. All rights reserved.