是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
恕我直言,最好的办法是避免特殊测试。大多数时候,使用生成器是一种测试:
thing_generated = False
# Nothing is lost here. if nothing is generated,
# the for block is not executed. Often, that's the only check
# you need to do. This can be done in the course of doing
# the work you wanted to do anyway on the generated output.
for thing in my_generator():
thing_generated = True
do_work(thing)
如果这还不够好,您仍然可以执行显式测试。此时,thing将包含最后生成的值。如果没有生成任何内容,它将是未定义的—除非您已经定义了该变量。你可以检查东西的价值,但那有点不可靠。相反,只需在块内设置一个标志,然后检查它:
if not thing_generated:
print "Avast, ye scurvy dog!"
其他回答
有一个非常简单的解决方案:如果next(generator,-1) == -1,那么生成器是空的!
使用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
此函数返回的迭代器将等效于作为参数传入的原始迭代器。
Bool (generator)将返回正确的结果
我发现只有这个解决方案也适用于空迭代。
def is_generator_empty(generator):
a, b = itertools.tee(generator)
try:
next(a)
except StopIteration:
return True, b
return False, b
is_empty, generator = is_generator_empty(generator)
或者如果你不想使用异常来尝试使用
def is_generator_empty(generator):
a, b = itertools.tee(generator)
for item in a:
return False, b
return True, b
is_empty, generator = is_generator_empty(generator)
在标记的解决方案中,您不能将其用于空生成器,如
def get_empty_generator():
while False:
yield None
generator = get_empty_generator()
要查看生成器是否为空,只需尝试获得下一个结果。当然,如果你还没有准备好使用这个结果,那么你必须存储它,以便以后再次返回。
下面是一个包装器类,可以添加到现有的迭代器中以添加__nonzero__测试,因此您可以通过简单的if查看生成器是否为空。它也可以变成一个装饰器。
class GenWrapper:
def __init__(self, iter):
self.source = iter
self.stored = False
def __iter__(self):
return self
def __nonzero__(self):
if self.stored:
return True
try:
self.value = next(self.source)
self.stored = True
except StopIteration:
return False
return True
def __next__(self): # use "next" (without underscores) for Python 2.x
if self.stored:
self.stored = False
return self.value
return next(self.source)
下面是你如何使用它:
with open(filename, 'r') as f:
f = GenWrapper(f)
if f:
print 'Not empty'
else:
print 'Empty'
请注意,您可以在任何时候检查空,而不仅仅是在迭代的开始。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录