是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
要查看生成器是否为空,只需尝试获得下一个结果。当然,如果你还没有准备好使用这个结果,那么你必须存储它,以便以后再次返回。
下面是一个包装器类,可以添加到现有的迭代器中以添加__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'
请注意,您可以在任何时候检查空,而不仅仅是在迭代的开始。
其他回答
如果你在使用生成器之前需要知道,那么不,没有简单的方法。如果你可以等到你使用生成器之后,有一个简单的方法:
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')
使用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
此函数返回的迭代器将等效于作为参数传入的原始迭代器。
为了表达我的“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
也许这不是最好的方法,主要是因为它会消耗生成器,但对我来说却是可行的。
>>> gen = (i for i in [])
>>> next(gen)
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
next(gen)
StopIteration
在生成器结束时引发StopIteration,因为在您的情况下立即到达结束,因此引发异常。但通常你不应该检查下一个值是否存在。
你可以做的另一件事是:
>>> gen = (i for i in [])
>>> if not list(gen):
print('empty generator')
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录