是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
在我的例子中,我需要知道在我将一组生成器传递给一个函数之前,它是否已经填充,该函数合并了这些项,即zip(…)。解决方案与公认的答案相似,但又有足够的不同:
定义:
def has_items(iterable):
try:
return True, itertools.chain([next(iterable)], iterable)
except StopIteration:
return False, []
用法:
def filter_empty(iterables):
for iterable in iterables:
itr_has_items, iterable = has_items(iterable)
if itr_has_items:
yield iterable
def merge_iterables(iterables):
populated_iterables = filter_empty(iterables)
for items in zip(*populated_iterables):
# Use items for each "slice"
我的特定问题具有这样的属性,即可迭代对象要么为空,要么具有完全相同数量的条目。
其他回答
>>> 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')
对于这种显而易见的方法,我很抱歉,但最好的方法是:
for item in my_generator:
print item
现在您已经检测到在使用生成器时它是空的。当然,如果生成器为空,项将永远不会显示。
这可能不完全适合您的代码,但这就是生成器的习惯用法:迭代,所以您可能会稍微改变您的方法,或者根本不使用生成器。
我用求和函数解出来了。请参阅下面我使用glob的示例。Iglob(返回一个生成器)。
def isEmpty():
files = glob.iglob(search)
if sum(1 for _ in files):
return True
return False
*这可能不适用于巨大的生成器,但对于较小的列表应该表现得很好
我讨厌提供第二个解决方案,特别是一个我自己不会使用的解决方案,但是,如果你绝对必须这样做,并且不消耗生成器,就像在其他答案中一样:
def do_something_with_item(item):
print item
empty_marker = object()
try:
first_item = my_generator.next()
except StopIteration:
print 'The generator was empty'
first_item = empty_marker
if first_item is not empty_marker:
do_something_with_item(first_item)
for item in my_generator:
do_something_with_item(item)
现在我真的不喜欢这个解决方案,因为我相信这不是生成器的使用方式。
要查看生成器是否为空,只需尝试获得下一个结果。当然,如果你还没有准备好使用这个结果,那么你必须存储它,以便以后再次返回。
下面是一个包装器类,可以添加到现有的迭代器中以添加__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'
请注意,您可以在任何时候检查空,而不仅仅是在迭代的开始。
推荐文章
- 如何解窝(爆炸)在一个熊猫数据帧列,成多行
- 如何使用pip安装opencv ?
- 在pip冻结命令的输出中“pkg-resources==0.0.0”是什么
- 格式y轴为百分比
- 熊猫连接问题:列重叠但没有指定后缀
- 为什么空字典在Python中是一个危险的默认值?
- 在Python中,冒号等于(:=)是什么意思?
- Python "SyntaxError:文件中的非ascii字符'\xe2' "
- 如何从psycopg2游标获得列名列表?
- Python中dict对象的联合
- 如何有效地比较两个无序列表(不是集合)?
- 如何在交互式Python中查看整个命令历史?
- 如何显示有两个小数点后的浮点数?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?