假设我们有一个生成器函数
gen()
,我们不知道它是否为空。
如果它是空的,我们想执行一个特殊的函数
foo()
,否则我们想对迭代器的每个元素执行一个函数bar(elem)
。
我可以这样做:
is_empty = True
for elem in gen():
is_empty = False
bar(elem)
if is_empty: foo()
但这感觉不太Pythonic。还有其他办法吗?
你无法直接判断生成器是否为空。这是设计使然。生成器背后的一个关键原则是它们不会在内存中保存生成序列的所有项目。
但是你可以这样做:
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)
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)
您仍然需要查看生成器,但您可以干净利落地完成。
如果您有能力在遍历生成器的项目之前耗尽生成器,并且您的函数
foo()
返回None
,您可以考虑这样做:
for elem in list(gen()) or foo() or []:
bar(elem)
仅当第一个操作数为假时,
or
运算符才计算第二个操作数。