是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
对于这种显而易见的方法,我很抱歉,但最好的方法是:
for item in my_generator:
print item
现在您已经检测到在使用生成器时它是空的。当然,如果生成器为空,项将永远不会显示。
这可能不完全适合您的代码,但这就是生成器的习惯用法:迭代,所以您可能会稍微改变您的方法,或者根本不使用生成器。
其他回答
我发现只有这个解决方案也适用于空迭代。
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()
这是一个古老的问题,但之前没有人提出过,下面是这个问题:
for _ in generator:
break
else:
print('Empty')
你可以在这里阅读更多
简单地用itertools包装生成器。Chain,在第二个可迭代对象中放入一个表示可迭代对象的结尾的东西,然后简单地检查它。
Ex:
import itertools
g = some_iterable
eog = object()
wrap_g = itertools.chain(g, [eog])
现在剩下的就是检查我们附加到可迭代对象末尾的值,当你读取它时,它将表示结束
for value in wrap_g:
if value == eog: # DING DING! We just found the last element of the iterable
pass # Do something
我意识到这篇文章已经5年了,但我在寻找一种惯用的方法时发现了它,并没有看到我的解决方案发布出来。所以为了子孙后代:
import itertools
def get_generator():
"""
Returns (bool, generator) where bool is true iff the generator is not empty.
"""
gen = (i for i in [0, 1, 2, 3, 4])
a, b = itertools.tee(gen)
try:
a.next()
except StopIteration:
return (False, b)
return (True, b)
当然,我相信许多评论员会指出,这很俗气,而且只在某些有限的情况下有效(例如,生成器没有副作用)。YMMV。
在遍历生成器之前检查生成器符合LBYL编码风格。另一种方法(EAFP)是遍历它,然后检查它是否为空。
is_empty = True
for item in generator:
is_empty = False
do_something(item)
if is_empty:
print('Generator is empty')
这种方法也可以很好地处理无限生成器。
推荐文章
- 如何在交互式Python中查看整个命令历史?
- 如何显示有两个小数点后的浮点数?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?
- 当使用代码存储库时,如何引用资源的相对路径
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴
- 如何消除数独方块的凹凸缺陷?
- 为什么出现这个UnboundLocalError(闭包)?