是否有一种简单的方法来测试生成器是否没有项目,比如peek, hasNext, isEmpty之类的?
当前回答
为了表达我的“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
也许这不是最好的方法,主要是因为它会消耗生成器,但对我来说却是可行的。
其他回答
我用求和函数解出来了。请参阅下面我使用glob的示例。Iglob(返回一个生成器)。
def isEmpty():
files = glob.iglob(search)
if sum(1 for _ in files):
return True
return False
*这可能不适用于巨大的生成器,但对于较小的列表应该表现得很好
简单地用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
Quick-dirty解决方案:
next(generator, None)不是None
或者将None替换为任何你知道不在生成器中的值。
编辑:是的,这将跳过生成器中的一项。然而,有时我只是出于验证目的检查生成器是否为空,然后并不真正使用它。否则我就会这样做:
def foo(self):
if next(self.my_generator(), None) is None:
raise Exception("Not initiated")
for x in self.my_generator():
...
也就是说,如果您的生成器来自一个函数,如my_generator(),则此方法有效。
我意识到这篇文章已经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。
刚刚读到这篇文章,意识到缺少一个非常简单易懂的答案:
def is_empty(generator):
for item in generator:
return False
return True
如果我们不打算使用任何项,那么我们需要将第一项重新注入生成器:
def is_empty_no_side_effects(generator):
try:
item = next(generator)
def my_generator():
yield item
yield from generator
return my_generator(), False
except StopIteration:
return (_ for _ in []), True
例子:
>>> g=(i for i in [])
>>> g,empty=is_empty_no_side_effects(g)
>>> empty
True
>>> g=(i for i in range(10))
>>> g,empty=is_empty_no_side_effects(g)
>>> empty
False
>>> list(g)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录